Candidate SWG Draft

OGC Standard

OGC Cartographic Symbology - Part 1: Core Model & Encodings
Erwan Bocher Editor Olivier Ertz Editor Jerome Jacovella-St-Louis Editor Maxime Collombin Editor
Version: 2.0
Additional Formats: XML PDF DOC
OGC Standard

Candidate SWG Draft

Document number:18-067r4
Document type:OGC Standard
Document subtype:Implementation
Document stage:Candidate SWG Draft
Document language:English

License Agreement

Use of this document is subject to the license agreement at https://www.ogc.org/license

Suggested additions, changes and comments on this document are welcome and encouraged. Such suggestions may be submitted using the online change request form on OGC web site: http://ogc.standardstracker.org/




I.  Abstract

This OGC Cartographic Symbology Standard defines a Conceptual Model, a Logical Model and Encodings for describing symbology rules for the portrayal of geographical data. The targets of this Standard are symbology encodings and cartographic rendering engines.

The Standard is modularized into multiple requirements classes, with a minimal core describing an extensible framework, with clear extension points, for defining styles consisting of styling rules selected through expressions and applying symbolizers configured using properties.

The Standard defines a number of additional conformance classes covering a large number of essential portrayal use cases for symbolizing both vector data and coverage data.

Finally, the Standard defines two encodings for the logical model: one based on JSON which can be readily parsed by JSON parsers, as well as a more expressive encoding better suited for hand-editing inspired from Web Cartographic Styled Sheets (CSS) and related cartographic symbology encodings.

Additional encodings can be defined that can conform to the logical model, and existing encodings can be mapped fully or partially to the conceptual model defined in this Standard.

The granularity of the requirements classes facilitates conformance for encodings and rendering engines based on their supported capabilities.

Future parts may extend this Standard by defining additional symbolizer properties, system identifiers, or new types of expressions.

II.  Keywords

The following are keywords to be used by search engines and document catalogues.

ogcdoc, OGC document, style, symbology, conceptual, core, modular, neutral, portrayal


III.  Preface

Example — Preface

This Standard is intended as a successor to the Symbology Encoding standard (SE 1.1) and the OGC Symbology Core Conceptual Model (“SymCore” 1.0). This Standard focuses primarily on describing symbology rules to be applied by a rendering engine to symbolize geospatial data. It also features a rich and extensible selector expression system which determines whether a particular symbology rule is to be applied or not by the rendering engine. In particular, it introduces a “system identifier” which can be mapped to concepts such as a particular layer, feature type or collection. Such concepts are used in OGC Web Services (including the Web Mapping Service (WMS) Style Layer Descriptor profile (SLD)), Web API Standards such as OGC API — Maps to render the data, and OGC API — Styles to provide styles, as well as data stores such as OGC GeoPackage (in which styles could also be stored using a portrayal extension). This Standard therefore follows the same motivation that split up SLD 1.0 (SLD 1.1 and SE 1.1) and defines requirements are not specific to any service (e.g., Web Map Service), are independent, and allow the concepts to be reused by other Standards willing to address aspects related to cartography. A general and portable symbology model is defined for use across the broad OGC Standards baseline, to be applied to geospatial datasets as well as online geospatial data and mapping services.

An important goal of this Standard is to enable richer symbology capabilities. This can be achieved through modularity which comes with extensibility. SE 1.1 is not modular per se, while this Standard is designed to be so by defining multiple requirements classes and the ability to conform with them at either the conceptual level or at the logical model. It also defines requirements classes for two encodings conforming to both the logical model and the conceptual model. The core coformance class covers the basic mechanics of defining a Style with StylingRules applying a Symbolizer, as well as how Expressions can be used to select whether a rule should be applied or not (Selectors). This provides two extension mechanisms that can be used by the additional requirements classes defined in this Standard as well by those introduced in future extension parts: new properties can be added to the Symbolizer class while defining their associated behavior, while new types of Expressions or System Identifiers can also be defined to be used within a Selector Expression or a ParameterValue Expression.

In contrast to the OGC Symbology Core Conceptual Model version 1.0, this version is clarified to not only be defining a conceptual model, but also a specific logical model. This newer version also defines a conceptual and logical model for expressions, which provides one specific mechanism for extension. This Standard clarifies that requirements classes extending this Standard can define additional properties for the Symbolizer class, providing the second extension mechanism. This Standard also includes symbology requirements classes covering the most common use cases for portraying both vector feature data as well as coverage data. Finally, this Standard defines two encodings conforming to the logical model. The more concrete nature of this standard better reflects the fact that it is an OGC Implementation Standard, and recognizes that for rendering engines to implement this Standard and for new or existing encodings to be mapped to the conceptual model of this Standard, the Standard needs to at least cover the essential portrayal use cases. This is demonstrated in a map gallery annex illustrating the various requirements classes coming into play for different use cases of varying complexity. The included encodings for the logical model readily allow to express all of the symbology capabilities defined in this Standard and should greatly facilitate interoperability and encourage implementation.

In summary, this Standard offers a consistent approach to:

  • provide the flexibility required to achieve adequate symbology rules for a variety of information communities; e.g., aviation symbols, weather symbols, thematic maps, etc.; and

  • achieve high-level styling interoperability without encoding dependencies, by allowing to define multiple encodings of the same logical model, as well as providing a framework to map the logical models used by other encodings to the one defined in this Standard through the conceptual model that this Standard also defines.

Potential implementations of SymCore are expected to enhance OGC Standards such as the OGC API family of Standards, GeoPackage, the Web Map Service (WMS), Web Feature Service (WFS), and others. By sharing a common core, and using an extension mechanism, integration of these Standards for the purposes of cartographic representation can be greatly simplified.

Attention is drawn to the possibility that some of the elements of this document may be the subject of patent rights. The Open Geospatial Consortium shall not be held responsible for identifying any or all such patent rights.

Recipients of this document are requested to submit, with their comments, notification of any relevant patent claims or other intellectual property rights of which they may be aware that might be infringed by any implementation of the standard set forth in this document, and to provide supporting documentation.

IV.  Security considerations

No security considerations have been made for this document.

V.  Submitting Organizations

The following organizations submitted this Document to the Open Geospatial Consortium (OGC):

  • HEIG-VD (School of Management and Engineering Vaud)
  • CNRS (National Center for Scientific Research)
  • Strategic ACI
  • IGN
  • Ecere

VI.  Submitters

All questions regarding this submission should be directed to the editors or the submitters:

NameAffiliation
Olivier Ertz (editor)Haute École d’Ingénierie et de Gestion du Canton de Vaud (HEIG-VD)
Erwan Bocher (editor)Laboratoire des Sciences et Techniques de l’information de la Communication et de la Connaissance / Centre national de la recherche scientifique (Lab-STICC CNRS)
Jérôme Jacovella-St-Louis (editor)Ecere Corporation
Maxime Collombin (editor)Haute École d’Ingénierie et de Gestion du Canton de Vaud (HEIG-VD)

1.  Scope

This Standard presents the requirements that define version 2.0 of the Styles and Symbology Model and Encodings — Part 1: Core (”SymCore 2.0”). A Model for the portrayal of geographic data is defined at both the conceptual and logical levels, in a modular manner through the use of separate requirements classes and specific extension points. The requirements classes defined by this first part cover the most common use cases for portraying geospatial vector features and coverages. Several scenarios of varying complexity and the associated requirements classes enabling them are illustrated in an annex. Two encodings are defined by this Standard: one based on JSON which can be readily parsed with a JSON parser, and another more expressive encoding inspired from Web Cascading Style Sheets (CSS) better suited for hand-editing style sheets. Future parts to this Standard may further extend the portrayal capabilities by defining additional requirements classes.

The Styles and Symbology Model is a new approach (Bocher E., Ertz O., 2018, see bibliography):

  • to provide the flexibility required to achieve adequate cartographic styling and fill the needs of a variety of information communities; e.g., aviation symbols, weather symbols, thematic maps, etc.; and

  • to achieve high level styling interoperability without encoding dependencies.

2.  Conformance

The OGC Styles and Symbology Model and Encodings defines multiple requirements classes and their associated conformance classes.

The standardization target for all conformance classes except the conformance classes defining encodings are both Encodings and Rendering engines. The standardization target for encodings are Rendering Engines and other applications accepting styles as input, as well as applications generating styles (e.g., style editors or converters).

The conformance of all Rendering engines with all conformance classes except the conformance classes defining encodings is with the conceptual model that will result in the expected visual output. The conformance of all Encodings with the conformance classes targeting them can be either at a conceptual level or at a logical level. Conformance at the logical level implies conformance at the conceptual level as well. An Encoding conforms to the logical model if a Style can be encoded using the classes and property names defined in this Standard with only a simple consistent set of rules mapping them to the encoding. An Encoding can conform to the conceptual model of any conformance class either partially (if it can only preserve some of the information) or fully (if it losslessly preserves all information).

The goal is to allow different encodings to have equivalent content and semantics so that they can be interoperable, by establishing a clear mapping from an encoding to the logical and/or conceptual model defined in this Standard. The granularity of conformance classes provides a mechanism to clearly indicate which portrayal capabilities are interoperable with other encodings or rendering engines implementing this Standard. Most Encodings and Rendering engines are expected to easily conform to the requirements classes for basic portrayal.

This document establishes a core requirements class with a URI of http://www.opengis.net/spec/cartosym-1/2.0/req/core.

Requirements and conformance test URIs defined in this document are relative to http://www.opengis.net/speccartosym-12.0.

2.1.  Requirements classes for basic portrayal

Requirements Class “Core” (http://www.opengis.net/spec/cartosym-1/2.0/req/core)

The Core Requirements Class specifies requirements that all encodings and rendering engines must support if claiming conformance with this Standard. The Core class defines how a Style is defined as a list of StylingRules consisting of a Symbolizer and an optional Selector expression, as well as a minimal set Symbolizer properties applicable to all types of geospatial data.

Requirements Class “Basic Vector Features Styling” (http://www.opengis.net/spec/cartosym-1/2.0/req/vector)

The Basic Vector Features Styling Requirements Class specifies requirements for styling vector features data, including referencing feature properties, specifying a fill and stroke to style vector geometry, as well as defining image, text or dot markers to symbolize points.

Requirements Class “Basic Coverage Styling” (http://www.opengis.net/spec/cartosym-1/2.0/req/coverage)

The Basic Coverage Styling Requirements Class specifies requirements for styling coverage data, including referencing coverage range values (e.g., bands), mapping them to color channels as well as defining colormaps.

Requirements Class “Basic Labeling” (http://www.opengis.net/spec/cartosym-1/2.0/req/labels)

The Basic Labeling Requirements Class specifies requirements for defining labels to be managed by a placement engine and rendered as a final pass on top of the map.

2.2.  Requirements classes for common portrayal capabilities

Requirements Class “Hill Shading” (http://www.opengis.net/spec/cartosym-1/2.0/req/hillshading)

The Hill Shading Requirements Class specifies requirements for styling elevation coverage data with a hill-shaded style.

Requirements Class “Font Outlines” (http://www.opengis.net/spec/cartosym-1/2.0/req/fontoutlines)

The Font Outlines Requirements Class specifies requirements for displaying fonts with outlines so that text can be legible on any background.

Requirements Class “Hatch Fills” (http://www.opengis.net/spec/cartosym-1/2.0/req/hatches)

The Hatch Filles Requirements Class specifies requirements for defining fils using hatches

Requirements Class “Stipple Fills” (http://www.opengis.net/spec/cartosym-1/2.0/req/stipples)

The Stipple Fills Requirements Class specifies requirements for defining fils using stipples

Requirements Class “Dashed Stroke” (http://www.opengis.net/spec/cartosym-1/2.0/req/dashes)

The Dashes Requirements Class specifies requirements for defining dashed strokes.

Requirements Class “Casing and Centerline” (http://www.opengis.net/spec/cartosym-1/2.0/req/casing)

The Casing and Centerline Requirements Class specifies requirements for defining strokes with built-in casing and centerline.

2.3.  Requirements classes for additional expression capabilities

Requirements Class “Parameter Values” (http://www.opengis.net/spec/cartosym-1/2.0/req/parametervalues)

The Parameter Values Requirements Class specifies requirements for using an Expression to define any property of a Symbolizer.

Requirements Class “Right-hand Identifiers” (http://www.opengis.net/spec/cartosym-1/2.0/req/righthand)

The Right-hand Identifiers Requirements Class specifies requirements for defining operation expressions with identifiers on the right-hand side.

Requirements Class “Conditional Expressions” (http://www.opengis.net/spec/cartosym-1/2.0/req/conditional)

The Conditional Expressions Requirements Class specifies requirements for defining conditional operation using a ternary [if] ? [then] : [else] structure.

Requirements Class “Variables” (http://www.opengis.net/spec/cartosym-1/2.0/req/variables)

The Variables Requirements Class specifies requirements for defining variables which can be mapped to a dynamic value controlled by an application, or used to facilitate customizing a style.

Requirements Class “Arithmetic Operators” (http://www.opengis.net/spec/cartosym-1/2.0/req/arithmetic)

The Arithmetic Operators Requirements Class specifies requirements for defining arithmetic operation expressions.

Requirements Class “Text Relation Operators” (http://www.opengis.net/spec/cartosym-1/2.0/req/textrelation)

The Text Relation Operators Requirements Class specifies requirements for defining text relation operation expressions.

Requirements Class “Function Expressions” (http://www.opengis.net/spec/cartosym-1/2.0/req/functions)

The Functions Requirements Class specifies requirements for defining function call expressions.

Requirements Class “Math Functions” (http://www.opengis.net/spec/cartosym-1/2.0/conf/rc-math)

The Math Functions Requirements Class specifies requirements for defining math functions to be used with numeric properties.

Requirements Class “Array Relation Functions” (http://www.opengis.net/spec/cartosym-1/2.0/req/arrayrelations)

The Array Relation Requirements Class specifies requirements for standardized array relation functions to be used with array properties.

Requirements Class “Text Manipulation Functions” (http://www.opengis.net/spec/cartosym-1/2.0/req/textmanipulation)

The Text Manipulation Requirements Class specifies requirements for standardized text manipulation functions to be used with text properties.

2.5.  Declaration of conformance

Conformance with this Standard shall be checked using all the relevant tests specified in Annex A (normative) of this document conformance to the respective conformance class is declared using the URIs listed in Table 1. A rendering engine accessible as an Web API can declare conformance to this Standard in its Conformance Declaration response.

The framework, concepts, and methodology for testing, and the criteria to be achieved to claim conformance are specified in the OGC Compliance Testing Policies and Procedures ( OGC 08-134r11) and the OGC Compliance Testing website.

All requirements-classes and conformance-classes described in this document are owned by the standard(s) identified.

Full conformance at the conceptual level but not at the logical level, which can losslessly preserve all information of the conceptual model defined in a particular requirements class but necessitates defining a custom mapping and cannot be automated from a simple consistent set of encoding rules, is declared by appending -concept to the conformance URI.

Partial conformance at the conceptual level which can preserve some but not all information of the conceptual model defined in a particular requirements class is declared by appending -partial-concept to the conformance URI.

Table 1 — Conformance class URIs

Conformance classURI
Corehttp://www.opengis.net/spec/cartosym-1/2.0/conf/core
Basic Vector Features Stylinghttp://www.opengis.net/spec/cartosym-1/2.0/conf/vector
Basic Coverage Stylinghttp://www.opengis.net/spec/cartosym-1/2.0/conf/coverage
Hill Shadinghttp://www.opengis.net/spec/cartosym-1/2.0/conf/hillshading
Basic Labelinghttp://www.opengis.net/spec/cartosym-1/2.0/conf/labels
Font Outlineshttp://www.opengis.net/spec/cartosym-1/2.0/conf/fontoutlines
Dashed Strokeshttp://www.opengis.net/spec/cartosym-1/2.0/conf/dashes
Casing and Centerlinehttp://www.opengis.net/spec/cartosym-1/2.0/conf/casing
Hatch Fillshttp://www.opengis.net/spec/cartosym-1/2.0/conf/hatches
Stipple Fillshttp://www.opengis.net/spec/cartosym-1/2.0/conf/stipples
Parameter Valueshttp://www.opengis.net/spec/cartosym-1/2.0/conf/parametervalues
Any right-hand operandshttp://www.opengis.net/spec/cartosym-1/2.0/conf/righthand
Conditional Expressionshttp://www.opengis.net/spec/cartosym-1/2.0/conf/conditional
Variableshttp://www.opengis.net/spec/cartosym-1/2.0/conf/variables
Arithmetic Operatorshttp://www.opengis.net/spec/cartosym-1/2.0/conf/arithmetic
Text Relation Operatorshttp://www.opengis.net/spec/cartosym-1/2.0/conf/textrelation
Function Expressionshttp://www.opengis.net/spec/cartosym-1/2.0/conf/functions
Math Functionshttp://www.opengis.net/spec/cartosym-1/2.0/conf/math
Array Relation Functionshttp://www.opengis.net/spec/cartosym-1/2.0/conf/arrayrelations
Text Manipulation Functionshttp://www.opengis.net/spec/cartosym-1/2.0/conf/textmanipulation
JSON Styles and Symbologyhttp://www.opengis.net/spec/cartosym-1/2.0/conf/json
Cartographic Symbology Cascading Style Sheetshttp://www.opengis.net/spec/cartosym-1/2.0/conf/cscss

3.  Normative references

The following documents are referred to in the text in such a way that some or all of their content constitutes requirements of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.

Jeff de La Beaujardiere: OGC 06-042, OpenGIS Web Map Service (WMS) Implementation Specification. Open Geospatial Consortium (2006). https://portal.ogc.org/files/?artifact_id=14416.

Markus Lupp: OGC 05-078r4, OpenGIS Styled Layer Descriptor Profile of the Web Map Service Implementation Specification. Open Geospatial Consortium (2007). https://portal.ogc.org/files/?artifact_id=22364.

Dr. Markus Mueller: OGC 05-077r4, OpenGIS Symbology Encoding Implementation Specification. Open Geospatial Consortium (2007). https://portal.ogc.org/files/?artifact_id=16700.

Panagiotis (Peter) A. Vretanos: OGC 09-026r2, OGC Filter Encoding 2.0 Encoding Standard — With Corrigendum. Open Geospatial Consortium (2014). http://www.opengis.net/doc/IS/fes/2.0.3.

Policy SWG: OGC 08-131r3, The Specification Model — Standard for Modular specifications. Open Geospatial Consortium (2009). https://portal.ogc.org/files/?artifact_id=34762&version=2.

A. Phillips, M. Davis: IETF RFC 4646, Tags for Identifying Languages. RFC Publisher (2006). https://www.rfc-editor.org/info/rfc4646.

ISO: ISO 19117:2012, Geographic information — Portrayal. International Organization for Standardization, Geneva (2012). https://www.iso.org/standard/46226.html.

The Unified Code for Units of Measure (UCUM), 2017 http://unitsofmeasure.org/ucum.html

W3C CSS Fonts chapter, 2016 https://www.w3.org/TR/CSS2/fonts.html#font-styling

Panagiotis (Peter) A. Vretanos, Clemens Portele: OGC 21-065r2, Common Query Language (CQL2). Open Geospatial Consortium (2024). http://www.opengis.net/doc/IS/cql2/1.0.

4.  Terms and definitions

This document uses the terms defined in OGC Policy Directive 49, which is based on the ISO/IEC Directives, Part 2, Rules for the structure and drafting of International Standards. In particular, the word “shall” (not “must”) is the verb form used to indicate a requirement to be strictly followed to conform to this document and OGC documents do not use the equivalent phrases in the ISO/IEC Directives, Part 2.

This document also uses terms defined in the OGC Standard for Modular specifications (OGC 08-131r3), also known as the ‘ModSpec’. The definitions of terms such as standard, specification, requirement, and conformance test are provided in the ModSpec.

For the purposes of this document, the following additional terms and definitions apply.

For the purposes of this document, the following terms and definitions apply.

This document used the terms defined in Policy Directive 492, which is based on the ISO/IEC Directives, Part 2, Rules for the structure and drafting of International Standards. In particular, the word “shall” (not “must”) is the verb form used to indicate a requirement to be strictly followed to conform to this standard and OGC documents do not use the equivalent phrases in the ISO/IEC Directives, Part 2.

This document also uses terms defined in the OGC Standard for Modular specifications (OGC 08-131r3), also known as the ‘ModSpec’. The definitions of terms such as standard, specification, requirement, and conformance test are provided in the ModSpec.

For the purposes of this document, the following additional terms and definitions apply.

Presentation of information to humans (Note 1 to entry: Within the scope of this International Standard, portrayal is restricted to the portrayal of geographic information). [SOURCE: ISO 19117:2012, 4.20]

Abstraction of reality specified by a geographic data model (feature, coverage…​). A layer may be represented using a set of symbols (Style). A layer contributes to a single geographic subject and may be a theme.

A sequence of rules of symbolizing instructions to be applied by a rendering engine on one or more features and/or coverages.

Automated process that produces graphics using a pipeline of layers and styles as inputs.

Conversion of digital graphics data into visual form (EXAMPLE Generation of an image on a video display) [SOURCE: ISO 19117:2012, 4.27]

6.  Conventions

This sections provides details and examples for any conventions used in the document. Examples of conventions are symbols, abbreviations, use of XML schema, or special notes regarding how to read the document.

6.1.  Abbreviated terms

The abbreviated terms clause gives a list of the abbreviated terms necessary for understanding this document.

IETF

Internet Engineering Task Force, https://ietf.org/

ISO

International Organization for Standardization, https://www.iso.org

OGC

Open Geospatial Consortium, www.opengeospatial.org

UML

Unified Modeling Language, http://www.uml.org/

7.  Overview

This Standard defines conformance classes for:

  • a core symbology conceptual and logical model based on Styles as a list of StylingRules consisting of a Symbolizer and optional Selector Expression (Section 7),

  • additional conformance classes extending this core model with:

    • basic portrayal capabilities of vector features (Section 8),

    • portrayal capabilities of coverage data (Section 9),

    • label placement and font outlines capabilities (Section 10),

    • advanced strokes capabilities, including dashed lines, casing and centerlines (Section 11),

    • advanced fill capabilities, including hatches and stipples (Section 12),

    • using expressions as parameter values for any symbolizer properties, using identifiers in the right side of operation expressions, conditional expressions and variables (Section 13),

    • arithmetic and text relation operators (Section 14),

    • function call expressions and standardized functions mathematics, temporal and array relations, as well as text manipulation (Section 15), and

  • two encodings for the logical and conceptual model covering all of these conformance classes:

    • an encoding based on JSON that can be readily parsed by JSON parser (Section 16), and

    • a more expressive encoding based on Web CSS which is better suited to hand-edit styles (Section 17).

In addition, the following annexes are included:

  • a normative Abstract Test Suite for the conformance classes (Annex A),

  • an informative mapping of SLD/SE and notable vendor extensions to the conceptual model and requirements classes (Annex B),

  • an informative map gallery of practical use cases alongside the styles used to generate the maps encoded in the Cartographic Symbology Cascading Style Sheets encoding (Annex C), and

  • an informative revision history (Annex D).

8.  Requirements Class “Core”

Requirements class 1: Core

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/core
Target typeStyle encodings and Renderers

8.1.  Overview

The requirements described in this section define the symbology core requirement class. The following UML diagram (Figure 1) shows the fundamental concepts of the Symbology Conceptual and Logical Model:

 

Figure 1 — Symbology Core Classes UML Diagram

8.2.  Metadata

Metadata is a container for descriptive information about a Style. It might includes a title, an abstract, a description, a list of authors, a list of keywords, and a list of geoDataClasses. All metadata elements are prefixed by a dot (.) as the first character of a line.

Table 2 — Metadata class

NameDefinitionData type and valueMultiplicity
nameA string value to reference the Metadatastring0..1
titleShort human-readable title for the stylestring0..1
descriptionDetailed description of the stylestring0..1
authorsAuthors of the stylestring0..*
keywordsList of keywordsstring0..*
geoDataClassesComma-separated URIs of GeoDataClasses allowing to identify data sources for which the style is suitablestring0..*

8.3.  Styles

A Style is the root concept of the Styles and Symbology Conceptual Model and consists of an ordered list of StylingRules. The StylingRules are to be applied in order so that rules selected later override earlier ones. This allows to compose styles in a cascading manner by inheriting from a base style then overriding some specific portrayal behaviors.

Table 3 — Style class

NameDefinitionData type and valueMultiplicity
stylingRulesStyling rules defining the styleStylingRule0..*

8.3.1.  Style stylingRules property

Requirement 1

Identifier/req/core/rules
A

An Encoding SHALL support individually storing and preserving the order of each StylingRule constituting a Style.

B

A Renderer SHALL support considering in order each individual StylingRule constituting a style.

C

The Symbolizer properties specified in a StylingRule appearing later in a Style’s list of rules and whose Selector evaluates to true SHALL be interpreted as overriding all Symbolizer properties set by earlier rules.

8.4.  Styling Rules

A StylingRule specifies that a particular Symbolizer (defining how to portray data) should be applied if the rule is selected based on a Selector expression (e.g., feature-property conditions or map scales). A StylingRule can contain nested rules, which will only be applied if the the parent rule’s Selector is evaluated to true, and whose Symbolizers will inherit from and override the parent StylingRule’s Symbolizer.

Table 4 — StylingRule

NameDefinitionData type and valueMultiplicity
nameA name for the rule (useful for generating legends)string0..1
selectorSelector defining the condition to apply the rule’s symbolizerExpression0..1
symbolizerSymbolizer to apply by the rendering engineSymbolizer0..1
nestedRulesAdditional styling rules to consider if this rule is selected partially overriding this rule’s symbolizerStylingRule0..*

8.4.1.  StylingRule selector property

The selector (also sometimes called a filter), for the rule is defined as a predicate expression evaluating to either true or false.

Example — Example showcasing a Style made of StylingRules using CSCSS encoding

 

Landuse    // Selector for this first rule
{
   // Symbolizer properties to be set if this rule is selected
   visibility: false;
}

Roads    // Selector for this second rule
{
   // Symbolizer properties to be set if this rule is selected
   visibility: false;

   // Nested rule only considered if this parent rule is selected
   [viz.sd < 200000] // Selector for this nested rule
   {
      // Symbolizer properties to be set if this nested rule is selected
      visibility: true;
   }
}

Requirement 2

Identifier/req/core/selector
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.4.2.  StylingRule nestedRules property

Requirement 3

Identifier/req/core/nested
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.5.  Symbolizers

A Symbolizer describes how to portray geographic data (e.g., vector features or gridded coverage data) based on a set of properties. This core requirements class only defines three basic properties relevant to most portrayal use cases. Separate requirements classes and later parts will extend this Symbolizer class with additional properties to provide more advanced portrayal capabilities.

Table 5 — Symbolizer class

NameDefinitionData type and valueMultiplicity
visibilityWhether to display the databool0..1
opacityDegree of opacityfloat0..1
zOrderSpecify a rendering orderint0..1

Example — CSCSS Example showcasing the limited symbolization possible with this Core requirements class

 

{
   visibility: false;

   Landuse
   {
      opacity = 0.5;
      zOrder = 1;
      visibility = true;
   }

   Buildings
   {
      opacity = 0.8;
      zOrder = 2;
      visibility = true;
   }
}

Requirement 4

Identifier/req/core/symbolizer
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.5.1.  Symbolizer visibility property

Requirement 5

Identifier/req/core/visibility
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.5.2.  Symbolizer opacity property

Requirement 6

Identifier/req/core/opacity
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.5.3.  Symbolizer zOrder property

Requirement 7

Identifier/req/core/zorder
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.6.  Expressions

Expressions are a syntactic entity that may be evaluated to determine its value (from Wikipedia). The concept has similar meaning to Expressions as defined in the OGC Filter Encoding 2.0 standard, and can also be implemented with the OGC Common Query Language (CQL2), with the caveat that the Expressions defined here are not restricted to evaluate to a boolean value as is the case for the first version of CQL2.

Expressions can be used in two places according to this Styles Symbology conceptual model: as a Selector defining the condition whether to apply a StylingRule or not, as well as to define the values of Symbolizer properties.

 

Figure 2 — Expression Classes UML Diagram

8.6.1.  Parameter Values

The use of an expression as a Symbolizer property is called a Parameter Value, where an Expression can be substituted where a particular data type is expected, in which case the Expression will be resolved to that expected data type. Conceptually, all Symbolizer properties can be specified using any type of expression Parameter Value, but this is not required by this core conformance class, and specific requirements classes such as the “Symbolizer Parameter Value Expresssions” requirements class enable this behavior. Without a requirements class specifying otherwise, only Literal Expressions compatible with the expected data type are allowed as Parameter Values.

Requirement 8

Identifier/req/core/parameters
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.6.2.  Identifier Expressions

An Identifier Expression is represented by a textual property that gets resolved at runtime.

8.6.2.1.  Properties / Fields Identifiers

Typical example of identifier expressions include feature properties (e.g., population) and coverage range values (e.g., a particular imagery band B8).

Requirement 9

Identifier/req/core/expressions-field-identifiers
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.6.2.2.  System Identifiers

 

Figure 3 — System Identifiers UML Diagram

One specific type of identifier expressions use System Identifiers. A System Identifier refers to an internal state of the system, or a particular aspect of the data being portrayed.

The following System Identifiers are defined by this conformance class:

A capability System Identifier declares available capabilities of the rendering engine.

 

Figure 4 — Capability System Identifiers UML Diagram

Table 6 — System Identifier capabilities

NameDefinitionData type and value
capabilitiesSupported capabilities of the rendering engineCapabilities
capabilities.vectorSupport for Basic Vector Features StylingBoolean (true if supported, false otherwise)
capabilities.coverageSupport for Basic Coverage StylingBoolean (true if supported, false otherwise)
capabilities.labelsSupport for Basic LabelingBoolean (true if supported, false otherwise)
capabilities.hillshadingSupport for Hill ShadingBoolean (true if supported, false otherwise)
capabilities.fontoutlinesSupport for Font OutlinesBoolean (true if supported, false otherwise)
capabilities.hatchesSupport for Hatch FillsBoolean (true if supported, false otherwise)
capabilities.stipplesSupport for Stipple FillsBoolean (true if supported, false otherwise)
capabilities.dashesSupport for Dashed StrokesBoolean (true if supported, false otherwise)
capabilities.casingSupport for Casing and CenterlineBoolean (true if supported, false otherwise)
capabilities.parametervaluesSupport for Parameter ValuesBoolean (true if supported, false otherwise)
capabilities.functionsSupport for Function ExpressionsBoolean (true if supported, false otherwise)
capabilities.mathSupport for Math FunctionsBoolean (true if supported, false otherwise)
capabilities.arrayrelationsSupport for Array Relation FunctionsBoolean (true if supported, false otherwise)
capabilities.textmanipulationSupport for Text Manipulation FunctionsBoolean (true if supported, false otherwise)
capabilities.arithmeticSupport for Arithmetic OperatorsBoolean (true if supported, false otherwise)
capabilities.textrelationSupport for Text Relation OperatorsBoolean (true if supported, false otherwise)
capabilities.righthandSupport for Any right-hand operandsBoolean (true if supported, false otherwise)
capabilities.conditionalSupport for Conditional ExpressionsBoolean (true if supported, false otherwise)
capabilities.variablesSupport for VariablesBoolean (true if supported, false otherwise)
capabilities.vendor.<vendorName>.<capability>Support for a capability defined by a vendor extensionBoolean (true if supported, false otherwise)

Example 1 — CSCSS Example showcasing the use of a capability System Identifier with a fallback Styling Rule

 

{
   stroke: { color: gray, width: 1, opacity: 0.5 }; // Thinner translucent gray stroke fallback if we don't have dashes
   [capabilities.dashes]
   {
      stroke: { color: black, width: 2, dashPattern: [ 2,1 ], opacity: 1 };
   }
}

Table 7 — Visualization System Identifiers

NameDefinitionData type and value
visualizationCurrent visualization stateVisualization
visualization.scaleDenominatorCurrent visualization scale denominatorfloat
visualization.dateTimeCurrent visualization date and timeDateTime
visualization.dateCurrent visualization dateDate
visualization.timeOfDayCurrent visualization time of dayTime
visualization.timeIntervalCurrent visualization time of dayTimeInterval
visualization.passCurrent visualization rendering passint

Example 2 — CSCSS Example showcasing scale-dependent selector using system identifiers

 

Roads
{
   visibility: false;

   [viz.sd < 200000] // Roads will only be visible at scale 1:200,000 and closer
   {
      visibility: true;
   }
}

Visualization Rendering Passes

Setting up symbolization rules for a selector on a visualization pass allows to render all data of the map using different set of symbolizers. A later pass will only begin after all data layers and their features / coverage cells have been rendered with the symbolizers set for earlier visualization passes.

See also the feature pass introduced in Basic Vector Styling requirements class, which allows to render the same feature multiple times with different symbolizers before rendering the next feature.

Table 8 — Styles & Symbology Visual Ordering Constructs

ConstructConstruct typeData typeBehavior description
zOrderSymbolizer propertyfloatIn a single pass, modify default order of features / layers
visualization.passSystem identifier for selectorintegerRender all selected geometry features / coverage cells of data layers more than once with different symbolization, or after whole map drawn in previous pass
feature.passSystem identifier for selectorintegerRender feature geometry / coverage cell more than once potentially with different symbolization before rendering next data point.

Table 9 — Month enumeration

Name
january
february
march
april
may
june
july
august
september
october
november
december

Table 10 — Date class

NameDefinitionData type and valueMultiplicity
yearint1
monthMonth1
dayint1

Table 11 — TimeOfDay class

NameDefinitionData type and valueMultiplicity
hourint1
minutesMonth1
secondsint1

Table 12 — Class TimeInstant

NameDefinitionData type and valueMultiplicity
dateDate1
timeTimeOfDay1

Table 13 — TimeInterval class

NameDefinitionData typeMultiplicity
startstart of the intervalTimeInstant1
endend of the intervalTimeInstant1

Example 3 — CSCSS Example showcasing visualization time-dependent selector using system identifiers

 

Landuse
{
   visibility: false;

   // Landuse will only be visible when visualization date is later than January 1, 2020
   [viz.date > DATE('2020-01-01')]
   {
      visibility: true;
   }
}

Table 14 — Layer System Identifiers

NameDefinitionData type and value
dataLayer.identifierIdentifier of data layersstring
dataLayer.typeData type of data layersenumeration: vector, coverage, …​

Example 4 — CSCSS Example showcasing selectors depending on layer identifiers and data type using system identifiers

 

[dataLayer.type = vector]
{
   // Display vector layers at 60% opacity by default
   opacity: 0.6;

   [dataLayer.identifier = 'Landuse']
   {
      // Except for Landuse that should show at 80% opacity
      opacity: 0.8;
   }

   // In CSCSS, the <layerid> syntax is equivalent
   // to [dataLayer.identifier = '<layerid>']
   Roads
   {
      opacity = 1.0; // and roads at 100% opacity
   }
}

Requirement 10

Identifier/req/core/expressions-system-identifiers
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

Requirement 11

Identifier/req/core/scale
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

Requirement 12

Identifier/req/core/time
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

Requirement 13

Identifier/req/core/layers
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.6.3.  Literal Expressions

 

Figure 5 — Literal Classes UML Diagram

A literal expression is an expression that has a fixed value in the encoding of the style. A similar literal class concept was originally defined in the OGC Filter Encoding 2.0 standard section 7.5.1.

The following types of literals are defined:

  • An integer literal represents a whole numeric value (CSCSS example: 123)

  • A real literal represents a real number (integer, fractional or irrational number) (CSCSS example: 0.85)

  • Text literals are Unicode character strings (CSCSS example: 'København')

  • A null literal represents an unset value (CSCSS example: null)

  • Enumeration value literals allow to refer by name to a set of pre-defined values associated with the context where they are used (CSCSS example: vector)

  • Boolean literals are a specialized type of enumeration literals which are either true or false (CSCSS example: false)

  • Array literals (see Array Expressions) (CSCSS example: (1, 2, 3))

  • Instance literals (see Instance Expressions) (CSCSS examples: Color(20, 100, 80) or Color(r: 20, g: 100, b: 80))

Requirement 14

Identifier/req/core/literals
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.6.4.  Operation Expressions

An Operation Expression performs an operation specified by an Operator on one, two or three operand expressions, depending on whether they unary, binary or ternary operators. This core requirements class defines only Logical and Relational operators. Implementations are also required to support prioritizing operations (typically encoded using parentheses: ( )). Other requirements classes introduce support for additional operators for arithmetic, text and bitwise operations. Without support for the Any right-hand operand requirements class, the right-hand operands of RelationExpressions are limited to LiteralExpressions.

Table 15 — OperationExpression class

NameDefinitionData type and valueMultiplicity
operand1First operandExpression0..1
operatorOperatorOperator1
operand2Second operandExpression1

 

Figure 6 — Core Logic and Relational Operators UML Diagram

This requirements class defines the following Logical Operators :

Table 16 — Logical Operators

NameCSCSS ExampleTypeDefinition
notnotunaryTrue if and only if the operand is false
andandbinaryTrue if and only if both operands are true
ororbinaryTrue if and only if either or both of the operands is true

This requirements class defines the following Relational Operators:

Table 17 — Relational Operators

NameCSCSS ExampleTypeDefinition
equal=binaryThe first operand is equal to the second one
notEqual<>binaryThe first operand is not equal to the second one
is (null)isbinaryOnly used with null literal for second operand (the first operand is null)
isNot (null)is notbinaryOnly used with null literal for second operand (the first operand is not null)
lesser<binaryThe first operand is smaller than the second one
greater>binaryThe first operand is greater than the second one
lesserEqual<=binaryThe first operand is smaller than or equal to the second one
greaterEqual>=binaryThe first operand is greater than or equal to the second one
in (array)inbinaryOnly used with an array for second operand (the first operand is one of the elements of the array)
notIn (array)not inbinaryOnly used with an array for second operand (the first operand is not one of the elements of the array)
betweenbetween …​ andternaryThe first operand is between the second and third operands (inclusively)
notBetweennot between …​ andternaryThe first operand is not between the second and third operands (inclusively)

Example — CSCSS Example showcasing the use of logical and relational operators in a selector

 

Roads
{
   visibility: false;

   // Roads will be visible between scales 1:20,000 and 1:200,000
   [viz.sd > 20000 and viz.sd < 200000]
   {
      visibility: true;
   }
}

Requirement 15

Identifier/req/core/operations
A

An Encoding SHALL support defining operation expressions consisting of operands and an operator for unary, binary and ternary operators.

B

An Encoding SHALL support defining the priority of expressions using multiple operators (e.g., using parentheses: ( )).

C

A Renderer SHALL support evaluating operation expressions while respecting the priority of operations.

Requirement 16

Identifier/req/core/logical
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

Requirement 17

Identifier/req/core/relational
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.6.5.  Array Expressions

An array expressions defines zero, one, or more element expressions forming an ordered set.

CSCSS example: (123.0, viz.sd).

An array literal is a special type of array expression whose elements are all literals.

Requirement 18

Identifier/req/core/arrays
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.6.6.  Instance Expressions

An instance expressions instantiates an object of a class while optionally specifying values for member components. The default values for any member if not explicitly overridden can is specified by the class member definitions.

CSCSS examples:

  • DateTime(year: 2022, month: april, day: 6)

  • Color(r: 20, g: 100, b: 80))

An instance literal is a special type of instance expression assigning only literal expressions to its member components.

A Symbolizer may either set an object property with a complete new instance, or specifically override a particular member of that object property. This capability is particularly useful when using nested StylingRules, where a nested rule can inherit the Symbolizer from the parent StylingRule.

Example — CSCSS Example showcasing the use of logical and relational operators in a selector

 

Roads
{
   // Default to a gray stroke (completely replace stroke property)
   stroke: { gray };
   // For scales closer than 1:200,000 ...
   [viz.sd < 200000]
   {
      stroke.width: 5px; // inherit gray color, but modify the width to be 5 pixels.

      // For scales closer than 1:10,000, replace the stroke completely with a 5 meters blue stroke
      [viz.sd < 10000] { stroke: { blue, width: 5m } }
   }
}

Requirement 19

Identifier/req/core/instances
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.7.  Default class member values

The following default values are defined by this encoding.

Table 18 — Symbolizer

NameDefault value
visibilitytrue
opacity1
zOrder1
filldefault Fill
strokedefault Stroke
markerdefault Marker
alphaChannel1
colorChannelsFor multi-field coverage: fields[0], fields[1], fields[2]
singleChannelFor single-field coverage: fields[0]

Table 19 — Stroke class default values

NameDefault value
opacity1
width1 px
colorblack

Table 20 — Fill class default values

NameDefault value
opacity1
colorwhite

Table 21 — Marker class default values

NameDefault value
elementsSingle default Dot

Table 22 — Dot class default values

NameDefault value
size10 px
colorwhite

Requirement 20

Identifier/req/core/default-values
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

8.8.  Vendor Extensions

This core requirements class specifies two ways to extend the model to custom vendor extensions. First, new Symbolizer properties can be defined. Second, System Identifiers can be extended with new identifiers.

In both cases, the vendor extension needs to be prefixed with: vendor.<vendor name> followed by the custom property or identifier name.

The datatype could be any of the existing types from the core model and standard extensions or new ones defined by the vendor.

Consumers should ignore any vendor extensions they do not understand.

If a custom Sytem Identifier is used in the Selector of a Rule, the entire Rule should be ignored if the System Identifier is not understood.

For new vendor extensions, these new capabilities can be identified using a System Identifier of the form capabilities.vendor.<vendorName>.<foo>.

If a custom property is used in the Parameter Value of a Symbolizer property, that property should be left set to the last Parameter Value that was understood.

The same principle applies for requirements clases that are not understood, whether defined in this core standard or additional extensions.

NOTE:  For this reason, the same property might be assigned different Parameter Values in the same Rule to provide for a fallback mechanism.

9.  Requirements Class “Basic Vector Features Styling”

9.1.  Overview

This requirements class adds support for defining how to Fill and render the Stroke of vector geometry. In addition, it defines the ability to specify a Marker consisting of one or more Graphic, to be rendered at the exact location of point geometry, at the centroid of polygon geometry, or at each point of line geometry.

9.1.1.  Symbolizer extension for vector features

 

Figure 7 — Basic Vector Features Extended Symbolizer Class UML Diagram

The following three new Symbolizer properties are defined by this requirements class:

Table 23 — Symbolizer class (vector features extension)

NameDefinitionData type and valueMultiplicity
fillFill to fill inside of geometriesFill0..1
strokeStroke to render geometry outlinesStroke0..1
markerMarker to render at geometries points or centroid (for polygons)Marker0..1

9.1.2.  Extended Identifiers for vector features

This requirements class defines as valid identifiers all of the accessible properties for a feature being portrayed with the name of those properties being the text of the identifier. Those identifiers are to be resolved with the value of that property. An encoding must support an escaping mechanism in cases where the name of a feature property might clash with a syntactic element.

9.1.2.1.  Extended System Identifiers

 

Figure 8 — Vector Features System Identifiers UML Class Diagram

In addition, the following new System Identifiers are defined by this requirements class:

Table 24 — System identifiers for vector features

NameDefinitionData type and value
feature.identifierIdentifier of a particular featurestring or number
feature.geometryDimensionDimension of geometry for a particular feature0 (points), 1 (lines), 2 (polygons), 3 (polyhedrons)
feature.passCurrent rendering pass for the same featureint
dataLayer.featuresGeometryDimensionDimension of feature geometry (if same for all features)0 (points), 1 (lines), 2 (polygons), 3 (polyhedrons), null (mixed)
9.1.2.1.1.  Feature Rendering Passes

This requirements class adds support for rendering vector geometry or coverage cells with multiple times with different symbolizer properties, as well as for re-ordering the rendering order so that either a single feature or an entire data layer is rendered after previous rendering passes have been completed.

See also the visualization pass defined in Core requirements class, which allows to render all data layers entire map with different symbolizers.

9.1.3.  Colors

 

Figure 9 — RGB Color class UML Diagram

Table 25 — RGB Color class

NameDefinitionTypeMultiplicity
rRed componentfloat1
gGreen componentfloat1
bBlue componentfloat1

9.1.4.  Fills

 

Figure 10 — UML Class Diagram of the Symbology Fill

A Fill defines the graphical symbolizing parameters required to draw the filling of a two-dimensional shape such as a polygon. Separate conformance classes can extend this Fill class with additional properties.

Table 26 — Fill class

NameDefinitionTypeMultiplicity
colorColor of the fillColor0..1
opacityOpacity of the fillfloat0..1

9.1.5.  Strokes

 

Figure 11 — Stroke Class UML Diagram

A Stroke defines the graphical symbolizing parameters for drawing an outline (e.g., for linear geometries or the exterior of a polygon geometry). As an abstract class and part of the base of the core graphical concepts, StrokeClass is a global point of extension to specify concrete ways to draw outlines. The StrokeClass properties are documented in the following table. By default the end of open subpaths are butt caped and at the corners of paths are miter joined when they are stroked.

A Stroke object inherits from a base StrokeStyling class, which is re-used in a separate requirements class for defining more complex strokes:

Table 27 — StrokeStyling class

NameDefinitionData type and valueMultiplicity
colorColor of the strokeColor0..1
opacityOpacity of the strokefloat0..1
widthWidth of the strokefloat (uom-qualified)0..1

9.1.5.1.  Graphical Units of Measure

 

Figure 12 — Graphical Units Enumeration UML Diagram

For styling parameters that define sizing and positioning of graphical objects (width, displacement, etc.), a specific unit of measure needs to be provided for the rendering engine. Therefore, properties where a unit of measure is relevant can be qualified with a particular uom codes.

Below is the list of allowed units of measure as per UCUM (except for pixel):

  • portrayal units: pixel, millimeter, inch, percentage; and

  • ground units: meter, foot.

The portrayal unit “pixel” is the default unit of measure. If available, the pixel size depends on the viewer client resolution, otherwise it is equal to 0.28mm x 0.28mm (~ 90 DPI).

9.1.6.  Markers

 

Figure 13 — Marker Class UML Diagram

A Marker inherits from a MultiGraphic which can contain multiple graphical elements:

Table 28 — MultiGraphic class

NameDefinitionData type and valueMultiplicity
elementsChildren elementsGraphic1..*

Without support for the Multi Graphics and Transforms requirements class, a MultiGraphic cannot contain another MultiGraphic.

A MultiGraphic itself inherits from a Graphic allowing to specify an opacity and a 2D position:

Table 29 — Graphic class

NameDefinitionData type and valueMultiplicity
opacityOpacityfloat0..1
positionPositionUnitPoint0..1

Table 30 — UnitPoint class

NameDefinitionData type and valueMultiplicity
xHorizontal positionfloat (uom-qualified)1
yVertical positionfloat (uom-qualified)1

9.1.6.1.  Dot Graphics

 

Figure 14 — Dot Class UML Diagram

A round Dot is one type of Graphic defined by this requirements class that can be used as part of a Marker.

A Dot inherits from a Shape class allowing to define a stroke which controls the color and size of the dot (with the stroke’s width property).

Table 31 — Shape

NameDefinitionTypeMultiplicity
strokeStroke with which to render the shape outlineStroke0..1

9.1.6.2.  Image Graphics

 

Figure 15 — Image Class UML Diagram

An Image is one type of graphic defined by this requirements class that can be used as part of a Marker.

Table 32 — Image

NameDefinitionTypeMultiplicity
imageThe image to useResource1
hotSpot0,0 position in the imageUnitPoint (uom-qualified)1
tintTint (multiplying white)Color1
blackTintBlack tint (used for blackColor1
alphaThresholdAlpha value considered pickablefloat1

The actual image content is defined by a Resource, which can be specified by one or multiple properties:

Table 33 — Resource class

NameDefinitionTypeMultiplicity
urlURL for online resourcestring0..1
path(preferably relative) path to local filestring0..1
idID within a database table or a spritestring0..1
typeSelected media type for the resourcestring0..1
extFile extension to build paths/URL with idstring0..1
spriteName of source sprite filestring0..1

9.1.6.3.  Text Graphics

 

Figure 16 — Text Class UML Diagram

A Text is one type of Graphic defined by this requirements class that can be used as part of a Marker.

Table 34 — Text

NameDefinitionData type and valueMultiplicity
textThe character string for the textstring (unicode)11
fontThe font to use for the textFont0..1
alignmentThe alignment to use for the textTextAlignment0..1
1 This requirements class requires support for identifier parameter value expression for the text property without any additional requirements class. This allows to display the value of feature properties with a Text Marker.

Table 35 — TextAlignment

NameDefinitionData type and valueMultiplicity
horzAlignmentHorizontal alignmentHAlignment0..1
vertAlignmentVertical alignmentVAlignment0..1

Table 36 — HAlignment enumeration

NameDefinition
leftLeft alignment
centerCenter alignment
rightRight alignment

Table 37 — VAlignment enumeration

NameDefinition
topTop alignment
middleMiddle alignment
bottomBottom alignment

The font property of a Text Graphic is defined uses the following Font class:

Table 38 — Font class

NameDefinitionData type and valueMultiplicity
faceFace namestring0..1
sizeSize of the font (pt)float0..1
boldUse bold stylebool0..1
italicUse italic stylebool0..1

9.2.  Requirements

9.2.1.  Basic Vector Features Styling

Requirements class 2: Basic Vector Features Styling

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/vector
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

9.2.1.1.  Symbolizer gamma property

Requirement 21

Identifier/req/vector/gamma
A

An Encoding SHOULD support defining a gamma Symbolizer property as a float.

B

A Renderer SHOULD support …​

9.2.1.2.  Symbolizer gradient property

Requirement 22

Identifier/req/vector/gradient
A

An Encoding SHALL support defining a gradient Symbolizer property as an object including a type and a stops array of color stops.

B

A Renderer SHALL support filling vector geometry based on a gradient property specifying a type and a stops array of color stops.

9.2.1.3.  Gradient type property

Requirement 23

Identifier/req/vector/gradient/type
A

An Encoding SHALL support defining a type property of a gradient Symbolizer as a string with a value of linear or radial.

B

A Renderer SHALL support filling vector geometry based on a gradient property specifying a type of linear or radial.

9.2.1.4.  Gradient stops property

Requirement 24

Identifier/req/vector/gradient/stops
A

An Encoding SHALL support defining a stops property of a gradient Symbolizer as an array of color stops.

B

A Renderer SHALL support filling vector geometry based on a gradient property specifying a stops array of color stops.

9.2.1.5.  Symbolizer fill property

Requirement 25

Identifier/req/vector/fill
A

An Encoding SHALL support defining a fill Symbolizer property as an object including a color and an opacity.

B

A Renderer SHALL support filling vector geometry based on a fill property specifying a color and an opacity.

9.2.1.6.  Symbolizer stroke property

Requirement 26

Identifier/req/vector/stroke
A

An Encoding SHALL support defining a stroke Symbolizer property as an object including a color and a units of measure-qualified (“uom-qualified”) width.

B

A Renderer SHALL support drawing the stroke of vector geometry based on a stroke property specifying a color and a uom-qualified width.

9.2.1.7.  Graphical Units of Measure

Requirement 27

Identifier/req/vector/units
A

An Encoding SHALL support qualifying distance properties identified as “uom-qualified” with a unit of measure (pixel, millimeter, inch, percentage, meter, foot).

B

A Renderer SHALL support applying the appropriate unit transformation when rendering elements specifying a uom-qualified distances.

9.2.1.8.  Symbolizer marker property

Requirement 28

Identifier/req/vector/marker
A

An Encoding SHALL support defining a marker Symbolizer property as an array of graphical elements (Graphics).

B

A Renderer SHALL support drawing the grahical elements of a marker at the points of vector geometry (for points and line strings) and at the centroid of polygons.

9.2.1.9.  Graphics

Requirement 29

Identifier/req/vector/graphics
A

An Encoding SHALL support defining graphical elements (graphics) specifying a uom-qualified 2D real position offsetting the graphic from its original position.

B

A Renderer SHALL support drawing the Graphics at the specified uom-qualified 2D position offset relative to its original position.

9.2.1.10.  Dot Graphics

Requirement 30

Identifier/req/vector/dot
A

An Encoding SHALL support defining a Dot Graphic inheriting from a base Shape class specifying a stroke, from which the color and the size of the point is inferred.

B

A Renderer SHALL support drawing the Graphics as a round dot using the width of its Stroke as the point size and in the color of the Stroke.

9.2.1.11.  Image Graphics

Requirement 31

Identifier/req/vector/image
A

An Encoding SHALL support defining an Image Graphic inheriting from a base Shape class specifying a stroke, from which the color and the size of the point is inferred.

B

A Renderer SHALL support drawing the Graphics as a round dot using the width of its Stroke as the point size and in the color of the Stroke.

9.2.1.12.  Text Graphics

Requirement 32

Identifier/req/vector/text
A

An Encoding SHALL support defining a Text Graphic with a text unicode string content, a font, and an alignment with a horizontal (horzAlignment: left, right or center) and vertical component (vertAlignment: top, middle, bottom).

B

A Renderer SHALL support drawing the text of a Text Graphic using the font and the alignment specified.

9.2.1.13.  Fonts

Requirement 33

Identifier/req/vector/fonts
A

An Encoding SHALL support defining Fonts with a face property indicating the face name (also known as the font family), a size specified in points, a bold flag indicating to use a bold weight if true, and an italic flag indicating to use an italic style if true.

B

A Renderer SHALL support drawing text using the fonts specified.

10.  Requirements Classes for Coverage styling

10.1.  Requirements Class “Basic Coverage Styling”

10.1.1.  Overview

This requirements class adds support for defining how to portray coverage data by mapping values from the range (e.g., individual imagery bands) to color channels or to a single channel, as well as providing an option to apply a color and/or opacity map based on the values.

 

Figure 17 — Basic Coverage Symbolizer Class UML Diagram

10.1.1.1.  Extended Identifiers

This requirements class defines as valid identifiers all of the accessible properties (the values of its range, as defined by the range type) for a coverage being portrayed with the name of those properties being the text of the identifier. Those identifiers are to be resolved with the value of that property. An encoding must support an escaping mechanism in cases where the name of a feature property might clash with a syntactic element.

10.1.1.2.  Extended Symbolizer

Table 39 — Extended Symbolizer properties

NameDefinitionData type and valueMultiplicity
colorChannelsValue of the Red, Green and Blue color channelsColor0..1
alphaChannelValue of the alpha (opacity) channelfloat0..1
singleChannelValue of a single (gray-scale) output channelfloat0..1
colorMapColor map to be applied based on singleCannelValueColor0..*
opacityMapOpacity map to be applied based on singleCannelValueOpacity0..*

This requirements class requires support for identifier parameter value expression for the red (r), green (g) and blue (b) components of the colorChannels, alphaChannel and singleChannel properties without any additional requirements class.

This allows to map the range values of a coverage to the output color channels.

The color map is defined with a Value/Color pair object:

Table 40 — ValueColor properties

NameDefinitionData type and valueMultiplicity
valueKey value for selecting this colorfloat1
colorColor associated with this valueColor1
nameLabel to use for this value when generating a legendstring0..1

Similarly, the opacity map is defined with a Value/Opacity pair object:

Table 41 — ValueOpacity properties

NameDefinitionData type and valueMultiplicity
valueKey value for selecting this colorfloat1
colorColor associated with this valueColor1
nameLabel to use for this value when generating a legendstring0..1

10.1.1.3.  Colors

Both the colorChannels and the colorMap properties use a Color class, specified using red, green and blue components. The ability to define Colors in other spaces (e.g., Lab, CMYK) is defined in separate requirements classes and applies wherever this basic RGB Color class is used.

Table 42 — Color

NameDefinitionData type and valueMultiplicity
rRedfloat1
gGreenfloat1
bBluefloat1

10.1.2.  Requirements

Requirements class 3: Basic Coverage Styling

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/coverage
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

10.1.2.1.  Symbolizer colorChannels property

Requirement 34

Identifier/req/coverage/color-channels
A

An Encoding SHALL support defining a colorChannels Symbolizer property as a Color object.

B

A Renderer SHALL support …​

10.1.2.2.  Symbolizer alphaChannel property

Requirement 35

Identifier/req/coverage/alpha-channel
A

An Encoding SHALL support defining a alphaChannel Symbolizer property as a float.

B

A Renderer SHALL support …​

10.1.2.3.  Symbolizer singleChannel property

Requirement 36

Identifier/req/coverage/single-channel
A

An Encoding SHALL support defining a singleChannel Symbolizer property as a float.

B

A Renderer SHALL support …​

10.1.2.4.  Symbolizer colorMap property

Requirement 37

Identifier/req/coverage/color-map
A

An Encoding SHALL support defining a colorMap Symbolizer property as an array of value (float) and color (Color) pairs which can be tagged with a name.

B

A Renderer SHALL support …​

10.1.2.5.  Symbolizer opacityMap property

Requirement 38

Identifier/req/coverage/opacity-map
A

An Encoding SHALL support defining a opacityMap Symbolizer property as an array of value (float) and opacity (float) pairs which can be tagged with a name.

B

A Renderer SHALL support …​

10.1.2.6.  Symbolizer gamma property

Requirement 39

Identifier/req/coverage/gamma
A

An Encoding SHOULD support defining a gamma Symbolizer property as a float.

B

A Renderer SHOULD support …​

10.1.2.7.  Symbolizer gradient property

Requirement 40

Identifier/req/coverage/gradient
A

An Encoding SHALL support defining a gradient Symbolizer property as an object including a type and a stops array of color stops.

B

A Renderer SHALL support filling vector geometry based on a gradient property specifying a type and a stops array of color stops.

10.1.2.8.  Gradient type property

Requirement 41

Identifier/req/coverage/gradient/type
A

An Encoding SHALL support defining a type property of a gradient Symbolizer as a string with a value of linear or radial.

B

A Renderer SHALL support filling vector geometry based on a gradient property specifying a type of linear or radial.

10.1.2.9.  Gradient stops property

Requirement 42

Identifier/req/coverage/gradient/stops
A

An Encoding SHALL support defining a stops property of a gradient Symbolizer as an array of color stops.

B

A Renderer SHALL support filling vector geometry based on a gradient property specifying a stops array of color stops.

10.2.  Requirements Class “Hill Shading”

10.2.1.  Overview

 

Figure 18 — HillShading Symbolizer Class UML Diagram

This requirements classand adds the capability to portray elevation coverages with a hill shading style. It depends on the Basic Coverage Styling requirements class.

10.2.1.1.  Extended Symbolizer

Table 43 — Extended Symbolizer properties

NameDefinitionData type and valueMultiplicity
hillShadingHill shading parametersHillShading0..1

Table 44 — HillShading properties

NameDefinitionData type and valueMultiplicity
factorFactor controlling the intensity of the shadingfloat0..1
sunOrientation of the sunAzimuthElevation0..1
colorMapColor map to be applied based on calculated shadeValueColor0..*
opacityMapOpacity map to be applied based on calculated shadeValueOpacity0..*

The sun property is specified using this AzimuthElevation class:

Table 45 — AzimuthElevation properties

NameDefinitionData type and valueMultiplicity
azimuthAzimuth angle relative to NorthAngle0..1
elevationElevation angle relative to the groundAngle0..1

10.2.2.  Requirements

Requirements class 4: Hill Shading

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/hillshading
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 3: http://www.opengis.net/spec/cartosym-1/2.0/req/coverage

10.2.2.1.  Symbolizer hillShading property

Requirement 43

Identifier/req/hillshading/hillshading
A

An Encoding SHALL support defining a hillshading Symbolizer property as an object including factor, sun, colorMap and opacityMap properties.

B

A Renderer SHALL support …​

10.2.2.2.  HillShading factor property

Requirement 44

Identifier/req/hillshading/factor
A

An Encoding SHALL support defining a factor HillShading property as a float.

B

A Renderer SHALL support …​

10.2.2.3.  HillShading sun property

Requirement 45

Identifier/req/hillshading/sun
A

An Encoding SHALL support defining a sun HillShading property as an object consisting of azimuth and elevation angle members representing the orientation of the sun relative to the terrain.

B

A Renderer SHALL support …​

10.2.2.4.  HillShading colorMap property

Requirement 46

Identifier/req/hillshading/color-map
A

An Encoding SHALL support defining a colorMap HillShading property as an array of value (float) and color (Color) pairs.

B

A Renderer SHALL support …​

10.2.2.5.  HillShading opacityMap property

Requirement 47

Identifier/req/hillshading/opacity-map
A

An Encoding SHALL support defining a opacityMap HillShading property as an array of value (float) and opacity (float) pairs.

B

A Renderer SHALL support …​

11.  Requirements Classes for Labeling

11.1.  Requirements Class “Basic Labeling”

11.1.1.  Overview

 

Figure 19 — Label Class UML Diagram

This requirements class adds support for labels that are placed using a placement algorithm (and may not always be placed) drawn as a separate pass on top of styled vector features and coverages. Like Markers, Labels inherit from the MultiGraphic class and may contain multiple graphical elements.

Table 46 — Extended Symbolizer Class

NameDefinitionTypeMultiplicity
labelGraphic placed and drawnsLabel0..1

11.1.3.  Basic Labeling

Requirements class 5: Basic Labeling

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/labels
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

11.1.3.1.  Basic Labeling

Requirement 48

Identifier/req/labels
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

11.2.  Requirements Class “Font Outlines”

11.2.1.  Overview

 

Figure 20 — Font outlines UML Diagram

This requirements class adds support for Text font outlines to improve readability on any background.

11.2.1.1.  Font Outlines

Table 47 — Extended Text Class

NameDefinitionTypeMultiplicity
outlineOutline for the textFontOutline0..1

Table 48 — FontOutline class

NameDefinitionData type and valueMultiplicity
sizeSize of the outlinefloat0..1
opacityOpacity of the outlinefloat0..1
colorColor of the outlineColor0..1

11.2.3.  Font Outlines

Requirements class 6: Font Outlines

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/font-outlines
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

11.2.3.1.  Font Outlines

Requirement 49

Identifier/req/font-outlines
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

12.  Requirements Classes for Advanced strokes

12.1.  Requirements Class “Dashes”

12.1.1.  Overview

This requirements class adds capabilities for strokes with the possibility to define:

  • the pattern of dashes and gaps used to paint the stroke

  • an offset on the rendering of the associated dash array.

12.1.3.  Dashes

Requirements class 7: Dashes

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/dashes
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

Implementations shall support all properties in the below table for style encodings and renderers.

 

Figure 21 — Dashed strokes class UML diagram

Table 49 — Extended Stroke class for dashes

NameDefinitionTypeMultiplicity
dashPatternDash patternint0..*
dashOffsetDash offsetUnitValue0..1

12.1.3.1.  Dash Pattern

Requirement 50

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/dashPattern
PrerequisiteRequirements class 7: http://www.opengis.net/spec/cartosym-1/2.0/req/dashes
A

An Encoding SHALL support defining a dashPattern property for the stroke symbolizer.

B

A Renderer SHALL support dashing vector geometry based on a dashPattern property.

Statement

 

Figure 22 — In black stroke without dashes, in red with a dash pattern alternating a long dash with a short gap.

12.1.3.2.  Dash Offset

Requirement 51

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/dashOffset
PrerequisiteRequirements class 7: http://www.opengis.net/spec/cartosym-1/2.0/req/dashes
A

An Encoding SHALL support defining a dashOffset property for the stroke symbolizer.

B

A Renderer SHALL support dashing vector geometry based on a dashOffset property.

Statement

 

Figure 23 — In black stroke without dashes, in red with a dash pattern preceded by an offset on the rendering of the associated dash pattern.

12.2.  Requirements Class “Casing and Centerline”

12.2.1.  Overview

 

Figure 24 — Casing and centerline strokes class UML diagram

This requirements class adds support for Strokes with a casing and centerline.

Table 50 — Extended Stroke class

NameDefinitionTypeMultiplicity
casingStyle of stroke casingStrokeStyling0..1
centerStyle of stroke center lineStrokeStyling0..1

12.2.3.  Casing and Centerline

Requirements class 8: Casing and Centerline

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/casing
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

12.2.3.1.  Casing casing operator

Requirement 52

Identifier/req/casing/casing
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

12.2.3.2.  Centerline center operator

Requirement 53

Identifier/req/casing/center
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

13.  Requirements Classes for Advanced fills

13.1.  Requirements Class “Hatch fills”

13.1.1.  Overview

This requirements class adds capabilities for defining hatch fills as a pattern of lines controlled by:

  • the width (thickness) of the line,

  • the distance between two lines,

  • the angle of the lines.

 

Figure 25 — Hatches Fills UML Diagram

13.1.2.  Requirements

Requirements class 9: Hatch fills

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/hatches
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

13.1.2.1.  Hatch fills

Requirement 54

Identifier/req/hatch-fills
A

Encodings and Renderers SHALL support a hatch property within the Fill class, defined as a Hatch class.

Table 51 — Fill class extended for hatches

NameDefinitionTypeMultiplicity
hatchLine-based hatch fillHatch0..1

Table 52 — Hatch class

NameDefinitionData type and valueMultiplicity
widthThickness of hatchfloat0..1
angleHatches orientation clockwise degreefloat0..1
distanceDistance between two consecutive hatchesfloat0..1

 

Figure 26 — Input shape to be hatched

 

Figure 27 — Default hatch properties (width : 1 px, angle : 45 °, distance : 10 px)

13.1.2.2.  Width

Requirement 55

Identifier/req/hatch-width
A

An Encoding SHALL support defining a width property for the hatch fill symbolizer.

B

A Renderer SHALL support fill hatching vector geometry based on a width property.

 

Figure 28 — A hatch lines with a width of 5px

13.1.2.3.  Angle

Requirement 56

Identifier/req/hatch-angle
A

An Encoding SHALL support defining an angle property for the hatch fill symbolizer.

B

A Renderer SHALL support fill hatching vector geometry based on an angle property.

 

Figure 29 — A hatch lines with an angle of 0 degree

13.1.2.4.  Distance

Requirement 57

Identifier/req/hatch-distance
A

An Encoding SHALL support defining a distance property for the hatch fill symbolizer.

B

A Renderer SHALL support fill hatching vector geometry based on a distance property.

 

Figure 30 — A hatch lines with a distance of 5px

13.2.  Requirements Class “Dot pattern fills”

13.2.1.  Overview

 

Figure 31 — Dotpattern Fills UML Diagram

This requirements class extends Fill capabilities by adding support for dot fills with a point-based pattern.

Table 53 — Fill class extended for dot patterns

NameDefinitionTypeMultiplicity
dotpatternPoint-based pattern fillDotpattern0..1

Table 54 — Dotpattern class

NameDefinitionData type and valueMultiplicity
distanceDistance between rendered points in the fillDistance0..1

Table 55 — Distance class

NameDefinitionData type and valueMultiplicity
horizontalHorizontal distance between rendered points in the fill.float0..1
verticalvertical distance between rendered points in the fill.float0..1

13.3.  Requirements Class “Stipple fills”

13.3.1.  Overview

This requirements class adds support for stipple fills. A stipple fill is a pattern of dots defined by a ratio property.

 

Figure 32 — Stipple Fills UML Diagram

13.3.2.  Requirements

Requirements class 10: Stipple fills

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/stipples
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

13.3.2.1.  Stipple fills

Implementations shall support all properties in the below table for style encodings and renderers.

Table 56 — Fill class extended for stippling

NameDefinitionTypeMultiplicity
stipplingRatioRatio of stippling dots according to area filledfloat (betwwen 0 an 1)0..1

Requirement 58

Identifier/req/stippling-ratio
A

An Encoding SHALL support defining a ratio property for the stipple fill symbolizer.

B

A Renderer SHALL support stipple fill vector geometry based on a ratio property.

 

Figure 33 — Fill a shape area with dots defined by a ratio (0.2, 0.5, 0.8)

14.  Requirements Classes for Additional expressions

14.1.  Requirements Class “Symbolizer Parameter Value Expressions”

14.1.1.  Overview

This requirements class adds support for using ParameterValues i.e., arbitrary Expressions (not only literals), for all Symbolizer properties.

14.1.2.  Requirements

Requirements class 11: Parameter Values

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/parameter-values
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

14.1.2.1.  Parameter Values

Requirement 59

Identifier/req/parameter-values
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

14.2.  Requirements Class “Any right-hand operands”

14.2.1.  Overview

This requirements class removes the restriction that right-hand side operands of RelationExpressions are limited to LiteralExpressions. For expressions encoded using CQL2, it is analogous to the CQL2 Property-Property comparison requirements class.

14.2.3.  Any right-hand operands

Requirements class 12: Any right-hand operands

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/righthand
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

14.2.3.1.  Any right-hand operands

Requirement 60

Identifier/req/righthand
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

14.3.  Requirements Class “Conditional Expressions”

14.3.2.  Conditional expressions

 

Figure 34 — Conditional Expressions UML Class Diagram

Table 57 — ConditionalExpression class

NameDefinitionTypeMultiplicity
conditionConditionExpression1
thenExpExpression resolving to when condition is trueExpession1
elseExpExpression resolving to when condition is falseExpession1

14.3.4.  Conditional Expressions

Requirements class 13: Conditional Expressions

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/conditional
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

14.3.4.1.  Conditional condition operator

Requirement 61

Identifier/req/conditional/condition
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

14.3.4.2.  Conditional thenExp operator

Requirement 62

Identifier/req/conditional/thenExp
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

14.3.4.3.  Conditional elseExp operator

Requirement 63

Identifier/req/conditional/elseExp
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

14.4.  Requirements Class “Variables”

14.4.1.  Overview

 

Figure 35 — Variable Expressions UML Class Diagram

This requirements class adds support for defining variables that can be used to facilitate re-use of definitions in encodings, as well as to provide configurable elements that can be associated with application control such as a slider or drop-down control.

14.4.1.1.  Variable expressions

Table 58 — VariableExpression class

NameDefinitionTypeMultiplicity
nameName of the variablestring1

14.4.3.  Variables

Requirements class 14: Variables

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/variables
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

14.4.3.1.  Variables

Requirement 64

Identifier/req/variables
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.  Requirements Classes for Additional Operators

15.1.  Requirements Class “Arithmetic Operators”

15.1.1.  Overview

This requirements class adds support for arithmetic operations.

 

Figure 36 — Arithmetic Operators UML Diagram

Table 59 — arithmetic

NameDefinitionData type and valueMultiplicity
addAdditionNumeric1..1
subSubtractionNumeric1..1
mulMultiplicationNumeric1..1
divDivisionNumeric1..1
intDivInteger DivisionNumeric1..1
modModulusNumeric1..1
powPowerNumeric1..1

15.1.3.  Arithmetic Operators

Requirements class 15: Arithmetic Operators

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/arithmetic
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

15.1.3.1.  Arithmetic add operator

Requirement 65

Identifier/req/arithmetic/add
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.1.3.2.  Arithmetic sub operator

Requirement 66

Identifier/req/arithmetic/sub
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.1.3.3.  Arithmetic mul operator

Requirement 67

Identifier/req/arithmetic/mul
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.1.3.4.  Arithmetic div operator

Requirement 68

Identifier/req/arithmetic/div
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.1.3.5.  Arithmetic intDiv operator

Requirement 69

Identifier/req/arithmetic/intDiv
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.1.3.6.  Arithmetic mod operator

Requirement 70

Identifier/req/arithmetic/mod
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.1.3.7.  Arithmetic pow operator

Requirement 71

Identifier/req/arithmetic/pow
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.2.  Requirements Class “Text Relation Operators”

15.2.1.  Overview

 

Figure 37 — TextRelation Operators UML Diagram

This requirements class adds more advanced support for evaluating the relation between text values, including the like operator, starts with, contains, ends with, as well as not variants for all these.

Table 60 — comparison

NameDefinitionData type and valueMultiplicity
likeLikeText1..1
notLikeNot LikeText1..1
containsContainsText1..1
startsWithStarts WithText1..1
endsWithEnds WithText1..1
notContainsDoes Not ContainText1..1
notStartsWithDoes Not Start WithText1..1
notEndsWithDoes Not End WithText1..1

15.2.3.  Text Relation Operators

Requirements class 16: Text Relation Operators

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/text-relation
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

15.2.3.1.  Text like operator

Requirement 72

Identifier/req/text-relation/like
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.2.3.2.  Text notLike operator

Requirement 73

Identifier/req/text-relation/notLike
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.2.3.3.  Text contains operator

Requirement 74

Identifier/req/text-relation/contains
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.2.3.4.  Text startsWith operator

Requirement 75

Identifier/req/text-relation/startsWith
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.2.3.5.  Text endsWith operator

Requirement 76

Identifier/req/text-relation/endsWith
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.2.3.6.  Text notContains operator

Requirement 77

Identifier/req/text-relation/notContains
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.2.3.7.  Text notStartsWith operator

Requirement 78

Identifier/req/text-relation/notStartsWith
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

15.2.3.8.  Text notEndsWith operator

Requirement 79

Identifier/req/text-relation/notEndsWith
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.  Requirements Classes for Functions

16.1.  Requirements Class “Function Expressions”

16.1.1.  Overview

This requirements class adds support for function call expressions.

16.1.1.1.  Function call expressions

 

Figure 38 — Functions UML Class Diagram

Table 61 — FunctionCallExpression class

NameTypeDefinitionmultiplicity
functionFunctionFunction to be called1
argumentsExpressionArguments to the function0..*

Table 62 — Function class

NameTypeDefinitionmultiplicity
namestringName1
parametersmap < string, type >Parameters1
returnTypetypeReturn type1

16.1.1.2.  Standard functions

A standard function is a Function with a pre-determined set of parameters, return value and behavior that may be registered with a URI. Requirements class in this section defines standard functions.

Table 63 — Standard functions URI mapping

KeyValueDefinition
uriFunctionA URI allows to identify standard functiona, even if identical function names are used in different encoding, extension or implementations for different behaviors.

16.1.3.  Functions

Requirements class 17: Functions

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/functions
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

16.1.3.1.  Function call expressions

Requirement 80

Identifier/req/functions/functions-call-expressions
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.1.3.2.  Standard functions

Requirement 81

Identifier/req/functions/standard-functions
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.  Requirements Class “Math Functions”

16.2.1.  Overview

 

Figure 39 — Math Functions UML Diagram

16.2.3.  Functions

Example — Math Functions

16.2.3.1.  Math abs function

Requirement 82

Identifier/req/math-functions/abs
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.2.  Math acos function

Requirement 83

Identifier/req/math-functions/acos
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.3.  Math asin function

Requirement 84

Identifier/req/math-functions/asin
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.4.  Math atan function

Requirement 85

Identifier/req/math-functions/atan
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.5.  Math atan2 function

Requirement 86

Identifier/req/math-functions/atan2
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.6.  Math ceil function

Requirement 87

Identifier/req/math-functions/ceil
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.7.  Math cos function

Requirement 88

Identifier/req/math-functions/cos
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.8.  Math cosh function

Requirement 89

Identifier/req/math-functions/cosh
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.9.  Math exp function

Requirement 90

Identifier/req/math-functions/exp
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.10.  Math floor function

Requirement 91

Identifier/req/math-functions/floor
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.11.  Math log function

Requirement 92

Identifier/req/math-functions/log
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.12.  Math log10 function

Requirement 93

Identifier/req/math-functions/log10
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.13.  Math max function

Requirement 94

Identifier/req/math-functions/max
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.14.  Math min function

Requirement 95

Identifier/req/math-functions/min
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.15.  Math pow function

Requirement 96

Identifier/req/math-functions/pow
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.16.  Math random function

Requirement 97

Identifier/req/math-functions/random
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.17.  Math rint function

Requirement 98

Identifier/req/math-functions/rint
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.18.  Math round function

Requirement 99

Identifier/req/math-functions/round
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.19.  Math sin function

Requirement 100

Identifier/req/math-functions/sin
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.20.  Math sinh function

Requirement 101

Identifier/req/math-functions/sinh
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.21.  Math sqrt function

Requirement 102

Identifier/req/math-functions/sqrt
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.22.  Math tan function

Requirement 103

Identifier/req/math-functions/tan
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.2.3.23.  Math tanh function

Requirement 104

Identifier/req/math-functions/tanh
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.3.  Requirements Class “Array Relation Functions”

16.3.1.  Overview

 

Figure 40 — Array Relation Functions UML Diagram

Table 64 — Array relation functions

NameParametersReturn typeDefinition
a_containedBy(array a, array b)bool
a_contains(array a, array b)bool
a_equals(array a, array b)bool
a_overlaps(array a, array b)bool

16.3.3.  Array Relation Functions

Requirements class 18: Array Relation Functions

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/array-relations
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

16.3.3.1.  Array a_containedBy operator

Requirement 105

Identifier/req/array-relations/a_containedBy
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.3.3.2.  Array a_contains operator

Requirement 106

Identifier/req/array-relations/a_contains
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.3.3.3.  Array a_equals operator

Requirement 107

Identifier/req/array-relations/a_equals
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.3.3.4.  Array a_overlaps operator

Requirement 108

Identifier/req/array-relations/a_overlaps
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.4.  Requirements Class “Text Manipulation Functions”

16.4.1.  Overview

 

Figure 41 — Text Manipulation Functions UML Diagram

Table 65 — Text manipulation functions

NameParametersReturn typeDefinition
caseInsensitize(string s)string
accentInsensitize(string s)string
lowerCase(string s)string
upperCase(string s)string
concatenate(string a, string b)string
substitute(string s, string a, string b)string
format(string f, …​)string

16.4.3.  Text Manipulation Functions

Requirements class 19: Text Manipulation Functions

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/text-manipulation
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

16.4.3.1.  Text caseInsensitize function

Requirement 109

Identifier/req/text-manipulation/caseInsensitize
A

An Encoding SHALL support …​

B

A Renderer SHALL support …​

16.4.3.2.  Text accentInsensitize function

Requirement 110

Identifier/req/text-manipulation/accentInsensitize
A

An Encoding SHALL support defining an accentInsensitize function that removes accents from a string.

B

A Renderer SHALL support removing accents from a string using the accentInsensitize function.

16.4.3.3.  Text lowerCase function

Requirement 111

Identifier/req/text-manipulation/lowerCase
A

An Encoding SHALL support defining a lowerCase function that converts a string to lowercase.

B

A Renderer SHALL support converting a string to lowercase using the lowerCase function.

16.4.3.4.  Text upperCase function

Requirement 112

Identifier/req/text-manipulation/upperCase
A

An Encoding SHALL support defining an upperCase function that converts a string to uppercase.

B

A Renderer SHALL support converting a string to uppercase using the upperCase function.

16.4.3.5.  Text concatenate function

Requirement 113

Identifier/req/text-manipulation/concatenate
A

An Encoding SHALL support defining a concatenate function that concatenates strings.

B

A Renderer SHALL support concatenating strings using the concatenate function

16.4.3.6.  Text substitute function

Requirement 114

Identifier/req/text-manipulation/substitute
A

An Encoding SHALL support defining a substitute function that replaces a substring with another string.

B

A Renderer SHALL support replacing a substring with another string using the substitute function.

16.4.3.7.  Text format function

Requirement 115

Identifier/req/text-manipulation/format
A

An Encoding SHALL support defining a format function that formats a string.

B

A Renderer SHALL support formatting a string using the format function.

17.  Requirements Class “JSON Styles and Symbology”

17.1.  Overview

This requirements class defines a JSON encoding for the Styles and Symbology Logical Model. The primary objective of this encoding is to be readily parsable and writable by machines using a standard JSON parser. Styles encoded with this encoding are not easily hand-edited by cartographers.

The encoding of expressions for both selectors and symbolizer parameter values in this encoding is based on the CQL2-JSON encoding.

In order to represent a partial update to an object property of a symbolizer, an object with all the modified properties is specified, as well as setting the "alter" property to true. For example, the following is equivalent to the CartoSym CSS representation of fill.color.r: 100, and will preserve the values of the other fill properties as well as the green and blue component of the fill color set by earlier rules or specified by defaults:

 

"fill": {
  
"alter": true,
  
"color": {
     
"alter": true,
     
"r": 100
  
}
}

Listing 1

A similar mechanism is also defined to modify only some elements of an array by using an object with "index" set to the zero-based array index, and "value" set to new value with which to update that array element. This mechanism can be combined with the partial update of objects to only modify some properties of an object array element, or to partially modify an array inside of an object property. For example, the following is equivalent to the CartoSym CSS representation of marker.elements[1]: Text { text: "Marker" }:

 

"marker": {
  
"alter": true,
  
"elements": {
     
"index": 1,
     
"value": { "type": "Text", "text": "Marker" }
  
}
}

Listing 2

Variables are encoded as JSON Pointer to a top-level "$variables" section in the same source file, or in an included file e.g., { "$ref": "#/$variables/myVariable" }. Base style sheets can be included using an “$include” property in the top-level object followed by either a single relative file path string or an array of relative file path strings to include. The styling rules from the included files will be included before any styling rules defined by the current file, allowing to override the symbolization fully or partially.

17.1.1.  Example

The following example demonstrates the CartoSym JSON encoding for the same example Basic Vector Styling for polygons equivalent to the one seen in the following CartoSym CSS section (Example 1 in 21.1.8.1. Basic Vector Styling).

 

{
  
"metadata":
  
{
     
"title": "Styling polygon vector features",
     
"abstract": "Basic vector features styling (polygons)"
  
},
  
"stylingRules": [
     
{
        
"selector":
        
{
           
"op": "and",
           
"args": [
              
{ "op": "=", "args": [ { "sysId": "dataLayer.id" }, "Landuse" ] },
              
{ "op": "=", "args": [ { "sysId": "dataLayer.type" }, "vector" ] },
              
{ "op": "=", "args": [ { "sysId": "dataLayer.featuresGeometryDimensions" }, 2 ] }
           
]
        
},
        
"symbolizer":
        
{
           
"$comment": "Do not show Landuse layer by default",
           
"visibility": false
        
},
        
"nestedRules": [
           
{
              
"$comment": "Show land use if zoomed in more than 1:200,000 for data valid within visualization's selected time range",
              
"selector":
              
{
                 
"op": "and",
                 
"args": [
                    
{ "op": "<", "args": [ { "sysId": "vis.id" }, 200000 ] },
                    
{ "op": ">=", "args": [ { "property": "validDate" }, { "sysId": "vis.timeInterval.start.date" } ] },
                    
{ "op": "<=", "args": [ { "property": "validDate" }, { "sysId": "vis.timeInterval.end.date" } ] }
                 
]
              
},
              
"symbolizer":
              
{
                 
"visibility": true,
                 
"opacity": 0.8,
                 
"zOrder": 1,
                 
"fill": { "color": "gray", "opacity": 0.5 },
                 
"stroke": { "color": "gray", "width": { "px": 2.0 }, "opacity": 1.0 }
              
},
              
"nestedRules": [
                 
{
                    
"$comment": "Select different fill and stroke color based on FunctionCode property",
                    
"selector": { "op": "=", "args": [ { "property": "FuntionCode" }, "parking" ] },
                    
"symbolizer":
                    
{
                       
"fill": { "alter": true, "color": "darkGray" },
                       
"stroke": { "alter": true, "color": [ 32, 32, 32 ] }
                    
}
                 
},
                 
{
                    
"selector": { "op": "=", "args": [ { "property": "FuntionCode" }, "park" ] },
                    
"symbolizer":
                    
{
                       
"fill": { "alter": true, "color": "darkGreen" },
                       
"stroke": { "alter": true, "color": "green" }
                    
}
                 
},
                 
{
                    
"selector": { "op": "=", "args": [ { "property": "FuntionCode" }, "commercial" ] },
                    
"symbolizer":
                    
{
                       
"fill": { "alter": true, "color": "lightGray" },
                       
"stroke": { "alter": true, "color": "lightGray" }
                    
}
                 
},
                 
{
                    
"$comment": "If zoomed in more than 1:10,000",
                    
"selector": { "op": "<", "args": [ { "sysId": "vis.sd" }, 10000 ] },
                    
"symbolizer":
                    
{
                       
"$comment": "Change stroke width to 4 pixels and add a text marker (positioned at centroid + horizontal offset) showing FunctionTitle property",
                       
"stroke": { "alter": true, "width": { "px": 4.0 } },
                       
"marker": {
                          
"elements": [
                             
{
                                
"type": "Text",
                                
"position": [20, 0],
                                
"$comment": "Offset 20 pixels to the right",
                                
"text": { "property": "FunctionTitle" },
                                
"alignment": [ "left", "top" ],
                                
"font": {
                                   
"face": "Arial",
                                   
"size": 14,
                                   
"bold": true,
                                   
"italic": true,
                                   
"opacity": 1.0,
                                   
"color": [ 0, 0, 0 ]
                                
}
                             
}
                          
]
                       
}
                    
},
                    
"nestedRules": [
                       
{
                          
"$comment": "Add icons at centroid based on land use function code property",
                          
"selector": { "op": "=", "args": [ { "property": "FuntionCode" }, "parking" ] },
                          
"symbolizer":
                          
{
                             
"marker": {
                                
"alter": true,
                                
"elements":
                                
{
                                   
"index": 1,
                                   
"value": {
                                      
"type": "Image",
                                      
"image": {
                                         
"uri": "http://example.com/parkingIcon",
                                         
"path": "parkingIcon.png",
                                         
"id": "parking",
                                         
"type": "image/png",
                                         
"ext": "png"
                                      
},
                                      
"hotSpot": [ { "pc": 50 }, { "pc": 50 } ],
                                      
"tint": "white",
                                      
"blackTint": "blue",
                                      
"alphaThreshold": 0.1
                                   
}
                                
}
                             
}
                          
}
                       
},
                       
{
                          
"$comment": "Add icons at centroid based on land use function code property",
                          
"selector": { "op": "=", "args": [ { "property": "FuntionCode" }, "park" ] },
                          
"symbolizer":
                          
{
                             
"marker": {
                                
"alter": true,
                                
"elements": {
                                   
"index": 1,
                                   
"value": {
                                      
"type": "Image",
                                      
"image": {
                                         
"uri": "http://example.com/park",
                                         
"path": "park.png",
                                         
"id": "park",
                                         
"type": "image/png",
                                         
"ext": "png"
                                      
},
                                      
"hotSpot": [ { "pc": 50 }, { "pc": 50 } ],
                                      
"tint": "white",
                                      
"blackTint": "blue",
                                      
"alphaThreshold": 0.1
                                   
}
                                
}
                             
}
                          
}
                       
},
                       
{
                          
"$comment": "Add icons at centroid based on land use function code property",
                          
"selector": { "op": "=", "args": [ { "property": "FuntionCode" }, "commercial" ] },
                          
"symbolizer":
                          
{
                             
"marker": {
                                
"alter": true,
                                
"elements": {
                                   
"index": 1,
                                   
"value": {
                                      
"type": "Image",
                                      
"image": {
                                         
"uri": "http://example.com/commercial",
                                         
"path": "commercial.png",
                                         
"id": "commercial",
                                         
"type": "image/png",
                                         
"ext": "png"
                                      
},
                                      
"hotSpot": [ { "pc": 50 }, { "pc": 50 } ],
                                      
"tint": "white",
                                      
"blackTint": "blue",
                                      
"alphaThreshold": 0.1
                                   
}
                                
}
                             
}
                          
}
                       
}
                    
]
                 
}
              
]
           
}
        
]
     
}
  
]
}

Listing

17.1.2.  JSON Schema

The following JSON Schema describes the encoding.

 

{
 
"$schema": "https://json-schema.org/draft/2019-09/schema",
 
"title": "OGC Cartographic Symbology - Part 1: Core Model and Encodings - JSON Schema",
 
"$ref": "#/$defs/style",
 
"allOf": [{
   
"$ref": "#/$defs/style"
 
}],
 
"$defs": {
   
"style": {
     
"type": "object",
     
"required": [ "stylingRules" ],
     
"properties": {
        
"$comment": { "type": "string" },
        
"$include": {
           
"oneOf": [
              
{ "type": "string" },
              
{ "type": "array", "items": { "type": "string" }, "minItems": 1 }
           
]
        
},
        
"metadata": {
           
"type": "object",
           
"properties":
           
{
              
"$comment": { "type": "string" },
              
"title": { "type": "string" },
              
"description": { "type": "string" },
              
"authors": { "type": "array", "items": { "type": "string" } },
              
"keywords": { "type": "array", "items": { "type": "string" } },
              
"geoDataClasses": { "type": "array", "items": { "type": "string", "format": "uri" } }
           
}
        
},
        
"stylingRules": {
           
"type": "array",
           
"items": { "$ref": "#/$defs/stylingRule" }
        
},
        
"$variables": { "type": "object" }
     
}
   
},
   
"stylingRule": {
     
"type": "object",
     
"properties":
     
{
        
"name": { "type": "string" },
        
"$comment": { "type": "string" },
        
"selector": { "$ref": "#/$defs/boolExpression" },
        
"symbolizer": { "$ref": "#/$defs/symbolizer" },
        
"nestedRules":
        
{
           
"type": "array",
           
"items": { "$ref": "#/$defs/stylingRule" }
        
}
     
}
   
},
   
"symbolizer": {
     
"type": "object",
     
"properties":
     
{
        
"$comment": { "type": "string" },

        
"visibility": { "$ref": "#/$defs/boolExpression" },
        
"opacity": { "$ref": "#/$defs/zeroToOne" },
        
"zOrder": { "$ref": "#/$defs/numericExpression" },

        
"fill": { "$ref": "#/$defs/fill" },
        
"stroke": { "$ref": "#/$defs/stroke" },
        
"marker": { "$ref": "#/$defs/marker" },
        
"label": { "$ref": "#/$defs/label" },

        
"colorChannels": { "$ref": "#/$defs/color0to1" },
        
"alphaChannel": { "$ref": "#/$defs/zeroToOne" },
        
"singleChannel": { "$ref": "#/$defs/zeroToOne" },
        
"colorMap": { "$ref": "#/$defs/colorMap" },
        
"opacityMap": { "$ref": "#/$defs/opacityMap" },

        
"hillShading": { "$ref": "#/$defs/hillShading" }
     
}
   
},
   
"fill":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "object",
           
"properties": {
              
"alter": { "type": "boolean" },
              
"color": { "$ref": "#/$defs/color" },
              
"opacity": { "$ref": "#/$defs/zeroToOne" },
              
"pattern": { "$ref": "#/$defs/graphic" },
              
"hatch": { "$ref": "#/$defs/hatch" },
              
"dotpattern": { "$ref": "#/$defs/dotpattern" },
              
"stipple": { "$ref": "#/$defs/stipple" }
           
}
        
}
      
]
   
},
   
"dotpattern":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
        
"distance": {
          
"oneOf": [
            
{ "$ref": "#/$defs/idOrFnExpression" },
            
{
              
"type": "array",
              
"minItems": 2,
              
"maxItems": 2,
              
"prefixItems": [
                
{ "$ref": "#/$defs/horizontal" },
                
{ "$ref": "#/$defs/vertical" }
              
]
            
},
            
{
              
"type": "object",
              
"properties":
              
{
                
"horizontal": { "$ref":  "#/$defs/unitValue"},
                
"vertical": { "$ref":  "#/$defs/unitValue"}
              
}
            
}
          
]
        
}
        
}
      
]
   
},
   
"hatch":
   
{
     
"oneOf": [
       
{ "$ref": "#/$defs/idOrFnExpression" },
       
{
         
"type": "object",
         
"properties": {
           
"width": { "$ref":  "#/$defs/unitValue" },
           
"angle": { "$ref": "#/$defs/numericExpression"},
           
"distance": { "$ref":  "#/$defs/unitValue"}
         
}
       
}
     
]
   
},
   
"stipple":
   
{
     
"oneOf": [
       
{ "$ref": "#/$defs/idOrFnExpression" },
       
{
         
"type": "object",
         
"properties": {
           
"ratio": { "$ref":  "#/$defs/numericExpression" }
         
}
       
}
     
]
   
},
   
"stroke":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"allOf": [
              
{ "$ref": "#/$defs/strokeStyling" },
              
{
                 
"type": "object",
                 
"properties":
                 
{
                    
"casing": { "$ref": "#/$defs/strokeStyling" },
                    
"centerLine": { "$ref": "#/$defs/strokeStyling" },
                    
"dashPattern": { "$ref": "#/$defs/dashPattern" },
                    
"pattern": { "$ref": "#/$defs/graphic" }
                 
}
              
}
           
]
        
}
      
]
   
},
   
"dashPattern":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "array",
           
"items":
           
{
              
"type": "integer",
              
"minimum": 0
           
}
        
},
        
{
           
"type": "object",
           
"required": [ "index", "value" ],
           
"properties": {
              
"index": { "type": "integer", "minimum": 0 },
              
"value": { "type": "integer", "minimum": 0 }
           
}
        
}
      
]
   
},
   
"marker": { "$ref": "#/$defs/multiGraphic" },
   
"label": {
      
"allOf": [
         
{ "$ref": "#/$defs/multiGraphic" },
         
{
            
"type": "object",
            
"properties":
            
{
               
"placement": { "$ref": "#/$defs/labelPlacement" }
            
}
         
}
      
]
   
},
   
"multiGraphic": {
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"allOf": [
              
{ "$ref": "#/$defs/abstractGraphic" },
              
{
                 
"type": "object",
                 
"required": [ "elements" ],
                 
"properties":
                 
{
                    
"elements": { "$ref": "#/$defs/graphicArray" }
                 
}
              
}
           
]
        
}
      
]
   
},
   
"graphicArray": {
      
"oneOf": [
        
{ "$ref": "#/$defs/arrayExpression" },
        
{
           
"type": "array",
           
"items": { "$ref": "#/$defs/graphic" }
        
},
        
{
           
"type": "object",
           
"required": [ "index", "value" ],
           
"properties": {
              
"index": { "type": "integer", "minimum": 0 },
              
"value": { "$ref": "#/$defs/graphic" }
           
}
        
}
      
]
   
},
   
"abstractGraphic": {
      
"type": "object",
      
"properties": {
         
"alter": { "type": "boolean" },
         
"position": { "$ref": "#/$defs/unitPoint" },
         
"opacity": { "$ref": "#/$defs/zeroToOne" }
      
}
   
},
   
"scale2D":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "array",
           
"minItems": 2,
           
"maxItems": 2,
           
"items": { "$ref": "#/$defs/numericExpression" }
        
},
        
{
           
"type": "object",
           
"properties":
           
{
              
"x": { "$ref": "#/$defs/numericExpression" },
              
"y": { "$ref": "#/$defs/numericExpression" },
              
"alter": { "type": "boolean" }
           
}
        
}
      
]
   
},
   
"scale3D":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "array",
           
"minItems": 3,
           
"maxItems": 3,
           
"items": { "$ref": "#/$defs/numericExpression" }
        
},
        
{
           
"type": "object",
           
"properties":
           
{
              
"x": { "$ref": "#/$defs/numericExpression" },
              
"y": { "$ref": "#/$defs/numericExpression" },
              
"z": { "$ref": "#/$defs/numericExpression" },
              
"alter": { "type": "boolean" }
           
}
        
}
      
]
   
},
   
"orientation3D":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "array",
           
"minItems": 4,
           
"maxItems": 4,
           
"items": { "$ref": "#/$defs/numericExpression" }
        
},
        
{
           
"type": "object",
           
"properties":
           
{
              
"w": { "$ref": "#/$defs/numericExpression" },
              
"x": { "$ref": "#/$defs/numericExpression" },
              
"y": { "$ref": "#/$defs/numericExpression" },
              
"z": { "$ref": "#/$defs/numericExpression" },
              
"alter": { "type": "boolean" }
           
}
        
},
        
{
           
"type": "object",
           
"properties":
           
{
              
"yaw": { "$ref": "#/$defs/numericExpression" },
              
"pitch": { "$ref": "#/$defs/numericExpression" },
              
"roll": { "$ref": "#/$defs/numericExpression" },
              
"alter": { "type": "boolean" }
           
}
        
}
      
]
   
},
   
"graphic": {
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{ "$ref": "#/$defs/image" },
        
{ "$ref": "#/$defs/shape" },
        
{ "$ref": "#/$defs/text" },
        
{ "$ref": "#/$defs/multiGraphic" }
      
]
   
},
   
"image": {
     
"allOf": [
        
{ "$ref": "#/$defs/abstractGraphic" },
        
{
            
"type": "object",
            
"required": [ "type", "image" ],
            
"properties":
            
{
               
"type": { "type": "string", "enum": [ "Image" ] },
               
"image": { "$ref": "#/$defs/resource" },
               
"hotSpot": { "$ref": "#/$defs/unitPoint" },
               
"tint": { "$ref": "#/$defs/color" },
               
"blackTint": { "$ref": "#/$defs/color" },
               
"alphaThreshold": { "$ref": "#/$defs/zeroToOne" }
            
}
        
}
     
]
   
},
   
"text": {
     
"allOf": [
        
{ "$ref": "#/$defs/abstractGraphic" },
        
{
            
"type": "object",
            
"required": [ "type", "text" ],
            
"properties":
            
{
               
"type": { "type": "string", "enum": [ "Text" ] },
               
"text": { "$ref": "#/$defs/characterExpression" },
               
"font": { "$ref": "#/$defs/font" },
               
"alignment": { "$ref": "#/$defs/textAlignment" }
            
}
        
}
      
]
   
},
   
"textAlignment": {
      
"oneOf": [
         
{ "$ref": "#/$defs/idOrFnExpression" },
         
{
            
"type": "array",
            
"minItems": 2,
            
"maxItems": 2,
            
"prefixItems": [
               
{ "$ref": "#/$defs/hAlignment" },
               
{ "$ref": "#/$defs/vAlignment" }
             
]
         
},
         
{
            
"type": "object",
            
"properties":
            
{
              
"hAlignment": { "$ref": "#/$defs/hAlignment" },
              
"vAlignment": { "$ref": "#/$defs/vAlignment" },
              
"alter": { "type": "boolean" }
            
}
         
}
      
]
   
},
   
"hAlignment": {
      
"oneOf": [
         
{ "$ref": "#/$defs/idOrFnExpression" },
         
{
            
"type": "string",
            
"enum": [ "left", "center", "right" ]
         
}
      
]
   
},
   
"vAlignment": {
      
"oneOf": [
         
{ "$ref": "#/$defs/idOrFnExpression" },
         
{
           
"type": "string",
           
"enum": [ "top", "middle", "bottom" ]
         
}
      
]
   
},
   
"font": {
      
"oneOf": [
         
{ "$ref": "#/$defs/idOrFnExpression" },
         
{
            
"type": "object",
            
"properties": {
               
"alter": { "type": "boolean" },
               
"face": { "$ref": "#/$defs/characterExpression" },
               
"size": { "$ref": "#/$defs/numericExpression" },
               
"bold": { "$ref": "#/$defs/boolExpression" },
               
"italic": { "$ref": "#/$defs/boolExpression" },
               
"underline": { "$ref": "#/$defs/boolExpression" },
               
"color": { "$ref": "#/$defs/color" },
               
"opacity": { "$ref": "#/$defs/zeroToOne" },
               
"outline": { "$ref": "#/$defs/fontOutline" }
            
}
         
}
      
]
   
},
   
"fontOutline": {
      
"oneOf": [
         
{ "$ref": "#/$defs/idOrFnExpression" },
         
{
            
"type": "object",
            
"properties": {
               
"alter": { "type": "boolean" },
               
"size": { "$ref": "#/$defs/numericExpression" },
               
"opacity": { "$ref": "#/$defs/zeroToOne" },
               
"color": { "$ref": "#/$defs/color" }
            
}
         
}
      
]
   
},
   
"abstractShape": {
     
"allOf": [
        
{ "$ref": "#/$defs/abstractGraphic" },
        
{
           
"type": "object",
           
"required": [ "type" ],
           
"properties": {
              
"type": { "type": "string" },
              
"stroke": { "$ref": "#/$defs/stroke" }
           
}
        
}
     
]
   
},
   
"shape": {
     
"oneOf": [
        
{ "$ref": "#/$defs/dot" }
       
]
   
},
   
"dot": {
     
"allOf": [
        
{ "$ref": "#/$defs/abstractShape" },
        
{
         
"type": "object",
         
"required": [ "type" ],
         
"properties":
         
{
            
"type": { "type": "string", "enum": [ "Dot" ] }
         
}
        
}
      
]
   
},
   
"abstractArc": {
     
"allOf": [
        
{ "$ref": "#/$defs/abstractShape" },
        
{
         
"type": "object",
         
"required": [ "startAngle", "deltaAngle", "radius" ],
         
"properties":
         
{
            
"center": { "$ref": "#/$defs/unitPoint" },
            
"radius": { "$ref": "#/$defs/unitValue" },
            
"startAngle": { "$ref": "#/$defs/angle" },
            
"deltaAngle": { "$ref": "#/$defs/angle" }
         
}
        
}
      
]
   
},
   
"resource": {
      
"type": "object",
      
"properties":
      
{
         
"alter": { "type": "boolean" },
         
"uri": { "$ref": "#/$defs/characterExpression" },
         
"path": { "$ref": "#/$defs/characterExpression" },
         
"id": { "$ref": "#/$defs/characterExpression" },
         
"type": { "$ref": "#/$defs/characterExpression" },
         
"ext": { "$ref": "#/$defs/characterExpression" },
         
"sprite": { "$ref": "#/$defs/characterExpression" }
      
}
   
},
   
"labelPlacement": {
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "object",
           
"properties":
           
{
              
"alter": { "type": "boolean" },
              
"priority": { "$ref": "#/$defs/numericExpression" },
              
"minSpacing": { "$ref": "#/$defs/numericExpression" },
              
"maxSpacing": { "$ref": "#/$defs/numericExpression" }
           
}
        
}
      
]
   
},
   
"strokeStyling":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "object",
           
"properties":
           
{
              
"alter": { "type": "boolean" },
              
"color": { "$ref": "#/$defs/color" },
              
"opacity": { "$ref": "#/$defs/zeroToOne" },
              
"width": { "$ref": "#/$defs/unitValue" }
           
}
        
}
      
]
   
},
   
"angle":
   
{
      
"oneOf": [
         
{ "$ref": "#/$defs/numericExpression" },
         
{ "type": "object", "properties": { "deg": { "$ref": "#/$defs/numericExpression" } }, "required": [ "deg" ] },
         
{ "type": "object", "properties": { "rad": { "$ref": "#/$defs/numericExpression" } }, "required": [ "rad" ] }
      
]
   
},
   
"unitValue":
   
{
      
"oneOf": [
         
{ "$ref": "#/$defs/numericExpression" },
         
{ "type": "object", "properties": { "px": { "$ref": "#/$defs/numericExpression" } }, "required": [ "px" ] },
         
{ "type": "object", "properties": { "mm": { "$ref": "#/$defs/numericExpression" } }, "required": [ "mm" ] },
         
{ "type": "object", "properties": { "cm": { "$ref": "#/$defs/numericExpression" } }, "required": [ "cm" ] },
         
{ "type": "object", "properties": { "in": { "$ref": "#/$defs/numericExpression" } }, "required": [ "in" ] },
         
{ "type": "object", "properties": { "pt": { "$ref": "#/$defs/numericExpression" } }, "required": [ "pt" ] },
         
{ "type": "object", "properties": { "em": { "$ref": "#/$defs/numericExpression" } }, "required": [ "em" ] },
         
{ "type": "object", "properties": { "pc": { "$ref": "#/$defs/numericExpression" } }, "required": [ "pc" ] },
         
{ "type": "object", "properties": { "m" : { "$ref": "#/$defs/numericExpression" } }, "required": [ "m"  ] },
         
{ "type": "object", "properties": { "ft": { "$ref": "#/$defs/numericExpression" } }, "required": [ "ft" ] }
      
]
   
},
   
"unitPoint":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "array",
           
"minItems": 2,
           
"maxItems": 3,
           
"items": { "$ref": "#/$defs/unitValue" }
        
},
        
{
           
"type": "object",
           
"properties":
           
{
              
"x": { "$ref": "#/$defs/unitValue" },
              
"y": { "$ref": "#/$defs/unitValue" },
              
"z": { "$ref": "#/$defs/unitValue" },
              
"alter": { "type": "boolean" }
           
}
        
}
      
]
   
},
   
"percent":
   
{
      
"anyOf": [
         
{ "$ref": "#/$defs/numericExpression" },
         
{ "type": "number", "minimum": 0.0, "maximum": 100.0 }
      
]
   
},
   
"zeroToOne":
   
{
      
"anyOf": [
         
{ "$ref": "#/$defs/numericExpression" },
         
{ "type": "number", "minimum": 0, "maximum": 1 }
      
]
   
},
   
"colorComponent0to255":
   
{
      
"anyOf": [
        
{ "$ref": "#/$defs/numericExpression" },
        
{ "type": "integer", "mininum": 0, "maximum": 255 }
      
]
   
},
   
"webColorName":
   
{
     
"type": "string",
     
"enum": [
        
"black",
        
"dimGray",
        
"dimGrey",
        
"gray",
        
"grey",
        
"darkGray",
        
"darkGrey",
        
"silver",
        
"lightGray",
        
"lightGrey",
        
"gainsboro",
        
"whiteSmoke",
        
"white",
        
"rosyBrown",
        
"indianRed",
        
"brown",
        
"fireBrick",
        
"lightCoral",
        
"maroon",
        
"darkRed",
        
"red",
        
"snow",
        
"mistyRose",
        
"salmon",
        
"tomato",
        
"darkSalmon",
        
"coral",
        
"orangeRed",
        
"lightSalmon",
        
"sienna",
        
"seaShell",
        
"chocolate",
        
"saddleBrown",
        
"sandyBrown",
        
"peachPuff",
        
"peru",
        
"linen",
        
"bisque",
        
"darkOrange",
        
"burlyWood",
        
"tan",
        
"antiqueWhite",
        
"navajoWhite",
        
"blanchedAlmond",
        
"papayaWhip",
        
"moccasin",
        
"orange",
        
"wheat",
        
"oldLace",
        
"floralWhite",
        
"darkGoldenrod",
        
"goldenrod",
        
"cornsilk",
        
"gold",
        
"khaki",
        
"lemonChiffon",
        
"paleGoldenrod",
        
"darkKhaki",
        
"beige",
        
"lightGoldenRodYellow",
        
"olive",
        
"yellow",
        
"lightYellow",
        
"ivory",
        
"oliveDrab",
        
"yellowGreen",
        
"darkOliveGreen",
        
"greenYellow",
        
"chartreuse",
        
"lawnGreen",
        
"darkSeaGreen",
        
"forestGreen",
        
"limeGreen",
        
"lightGreen",
        
"paleGreen",
        
"darkGreen",
        
"green",
        
"lime",
        
"honeyDew",
        
"seaGreen",
        
"mediumSeaGreen",
        
"springGreen",
        
"mintCream",
        
"mediumSpringGreen",
        
"mediumAquaMarine",
        
"aquamarine",
        
"turquoise",
        
"lightSeaGreen",
        
"mediumTurquoise",
        
"darkSlateGray",
        
"darkSlateGrey",
        
"paleTurquoise",
        
"teal",
        
"darkCyan",
        
"aqua",
        
"cyan",
        
"lightCyan",
        
"azure",
        
"darkTurquoise",
        
"cadetBlue",
        
"powderBlue",
        
"lightBlue",
        
"deepSkyBlue",
        
"skyBlue",
        
"lightSkyBlue",
        
"steelBlue",
        
"aliceBlue",
        
"dodgerBlue",
        
"slateGray",
        
"slateGrey",
        
"lightSlateGray",
        
"lightSlateGrey",
        
"lightSteelBlue",
        
"cornflowerBlue",
        
"royalBlue",
        
"midnightBlue",
        
"lavender",
        
"navy",
        
"darkBlue",
        
"mediumBlue",
        
"blue",
        
"ghostWhite",
        
"slateBlue",
        
"darkSlateBlue",
        
"mediumSlateBlue",
        
"mediumPurple",
        
"blueViolet",
        
"indigo",
        
"darkOrchid",
        
"darkViolet",
        
"mediumOrchid",
        
"thistle",
        
"plum",
        
"violet",
        
"purple",
        
"darkMagenta",
        
"magenta",
        
"fuschia",
        
"orchid",
        
"mediumVioletRed",
        
"deepPink",
        
"hotPink",
        
"lavenderBlush",
        
"paleVioletRed",
        
"crimson",
        
"pink",
        
"lightPink"
     
]
   
},
   
"color":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "object",
           
"properties":
           
{
              
"r": { "$ref": "#/$defs/colorComponent0to255" },
              
"g": { "$ref": "#/$defs/colorComponent0to255" },
              
"b": { "$ref": "#/$defs/colorComponent0to255" },
              
"alter": { "type": "boolean" }
           
}
        
},
        
{
           
"type": "array",
           
"items": { "$ref": "#/$defs/colorComponent0to255" },
           
"minItems": 3,
           
"maxItems": 3
        
},
        
{ "$ref": "#/$defs/webColorName" }
      
]
   
},
   
"color0to1":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "object",
           
"properties":
           
{
              
"r": { "$ref": "#/$defs/zeroToOne" },
              
"g": { "$ref": "#/$defs/zeroToOne" },
              
"b": { "$ref": "#/$defs/zeroToOne" },
              
"alter": { "type": "boolean" }
           
}
        
},
        
{
           
"type": "array",
           
"items": { "$ref": "#/$defs/zeroToOne" },
           
"minItems": 3,
           
"maxItems": 3
        
},
        
{ "$ref": "#/$defs/webColorName" }
      
]
   
},
   
"colorMap":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "array",
           
"items":
           
{
              
"type": "array",
              
"minItems": 2,
              
"maxItems": 3,
              
"prefixItems": [
                 
{ "$ref": "#/$defs/numericExpression" },
                 
{ "$ref": "#/$defs/color" },
                 
{ "type": "string" }
              
]
           
},
           
"minItems": 1
        
}
      
]
   
},
   
"opacityMap":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "array",
           
"items":
           
{
              
"type": "array",
              
"minItems": 2,
              
"maxItems": 3,
              
"prefixItems": [
                 
{ "$ref": "#/$defs/numericExpression" },
                 
{ "$ref": "#/$defs/zeroToOne" },
                 
{ "type": "string" }
              
]
           
},
           
"minItems": 1
        
}
      
]
   
},
   
"hillShading": {
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
            
"type": "object",
            
"properties": {
               
"factor": { "$ref": "#/$defs/numericExpression" },
               
"sun": { "$ref": "#/$defs/azimuthElevation" },
               
"colorMap": {
                 
"allOf": [
                  
{"$ref": "#/$defs/colorMap"},
                  
{"items": [
                    
{"type": "array",
                     
"minItems": 2,
                     
"maxItems": 3,
                     
"prefixItems": [
                        
{ "$ref": "#/$defs/zeroToOne" },
                        
{ "$ref": "#/$defs/color" },
                        
{ "type": "string" }
                     
]
                    
}
                  
]}]
               
},
               
"opacityMap": { "$ref": "#/$defs/hsOpacityMap" },
               
"alter": { "type": "boolean" }
            
}
        
}
      
]
   
},
   
"azimuthElevation": {
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
            
"type": "object",
            
"properties": {
               
"azimuth": { "$ref": "#/$defs/angle" },
               
"elevation": { "$ref": "#/$defs/angle" },
               
"alter": { "type": "boolean" }
            
}
        
}
      
]
   
},
   
"hsOpacityMap":
   
{
      
"oneOf": [
        
{ "$ref": "#/$defs/idOrFnExpression" },
        
{
           
"type": "array",
           
"items":
           
{
              
"type": "array",
              
"minItems": 2,
              
"maxItems": 3,
              
"prefixItems": [
                 
{ "$ref": "#/$defs/zeroToOne" },
                 
{ "$ref": "#/$defs/zeroToOne" },
                 
{ "type": "string" }
              
]
           
},
           
"minItems": 1
        
}
      
]
   
},
   
"idOrFnExpression": {
      
"anyOf": [
         
{ "$ref": "#/$defs/systemIdentifier" },
         
{ "$ref": "#/$defs/propertyRef" },
         
{ "$ref": "#/$defs/functionCall" },
         
{ "$ref": "#/$defs/conditionalExpression" }
      
]
   
},
   
"anyExpression": {
      
"anyOf": [
         
{ "$ref": "#/$defs/systemIdentifier" },
         
{ "$ref": "#/$defs/scalarExpression" },
         
{ "$ref": "#/$defs/geomExpression" },
         
{ "$ref": "#/$defs/temporalExpression" },
         
{ "$ref": "#/$defs/array" },
         
{ "type": null }
      
]
   
},
   
"systemIdentifier": {
      
"type": "object",
      
"required": [ "sysId" ],
      
"properties":
      
{
         
"sysId": {
            
"type": "string",
            
"enum": [
              
"dataLayer",
              
"dataLayer.id",
              
"dataLayer.type",
              
"dataLayer.features",
              
"dataLayer.featuresGeometry",
              
"dataLayer.featuresGeometryDimensions",
              
"feature",
              
"feature.id",
              
"feature.geometry",
              
"feature.geometryDimensions",
              
"vis",
              
"vis.sd",
              
"vis.date",
              
"vis.date.day",
              
"vis.date.month",
              
"vis.date.year",
              
"vis.dateTime",
              
"vis.dateTime.date",
              
"vis.dateTime.date.day",
              
"vis.dateTime.date.month",
              
"vis.dateTime.date.year",
              
"vis.dateTime.time",
              
"vis.dateTime.time.hour",
              
"vis.dateTime.time.minutes",
              
"vis.dateTime.time.seconds",
              
"vis.timeInterval",
              
"vis.timeInterval.start",
              
"vis.timeInterval.start.date",
              
"vis.timeInterval.start.date.day",
              
"vis.timeInterval.start.date.month",
              
"vis.timeInterval.start.date.year",
              
"vis.timeInterval.start.time",
              
"vis.timeInterval.start.time.hour",
              
"vis.timeInterval.start.time.minutes",
              
"vis.timeInterval.start.time.seconds",
              
"vis.timeInterval.end",
              
"vis.timeInterval.end.date",
              
"vis.timeInterval.end.date.day",
              
"vis.timeInterval.end.date.month",
              
"vis.timeInterval.end.date.year",
              
"vis.timeInterval.end.time",
              
"vis.timeInterval.end.time.hour",
              
"vis.timeInterval.end.time.minutes",
              
"vis.timeInterval.end.time.seconds",
              
"vis.timeOfDay",
              
"vis.timeOfDay.hour",
              
"vis.timeOfDay.minutes",
              
"vis.timeOfDay.seconds"
            
]
         
}
      
}
   
},
   
"boolExpression": {
       
"$dynamicAnchor": "boolExpression",
       
"oneOf": [
         
{ "$ref": "#/$defs/andOrExpression" },
         
{ "$ref": "#/$defs/notExpression" },
         
{ "$ref": "#/$defs/comparisonPredicate" },
         
{ "$ref": "#/$defs/spatialPredicate" },
         
{ "$ref": "#/$defs/temporalPredicate" },
         
{ "$ref": "#/$defs/arrayPredicate" },
         
{ "$ref": "#/$defs/functionCall" },
         
{ "$ref": "#/$defs/conditionalExpression" },
         
{ "type": "boolean" }
       
]
   
},
   
"andOrExpression": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [ "and", "or" ]
       
},
       
"args": {
         
"type": "array",
         
"minItems": 2,
         
"items": {
           
"$dynamicRef": "#boolExpression"
         
}
       
}
     
}
   
},
   
"notExpression": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [ "not" ]
       
},
       
"args": {
         
"type": "array",
         
"minItems": 1,
         
"maxItems": 1,
         
"items": {
           
"$dynamicRef": "#boolExpression"
         
}
       
}
     
}
   
},
   
"comparisonPredicate": {
     
"oneOf": [
       
{ "$ref": "#/$defs/binaryComparisonPredicate" },
       
{ "$ref": "#/$defs/isLikePredicate" },
       
{ "$ref": "#/$defs/textOpPredicate" },
       
{ "$ref": "#/$defs/isBetweenPredicate" },
       
{ "$ref": "#/$defs/isInListPredicate" },
       
{ "$ref": "#/$defs/isNullPredicate" }
     
]
   
},
   
"binaryComparisonPredicate": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [ "=", "<>", "<", ">", "<=", ">=" ]
       
},
       
"args": {
         
"$ref": "#/$defs/scalarOperands"
       
}
     
}
   
},
   
"scalarOperands": {
     
"type": "array",
     
"minItems": 2,
     
"maxItems": 2,
     
"prefixItems": [
       
{ "$ref": "#/$defs/scalarExpression" },
       
{ "$ref": "#/$defs/scalarExpression" }
     
]
   
},
   
"scalarExpression": {
     
"oneOf": [
       
{ "$ref": "#/$defs/characterExpression" },
       
{ "$ref": "#/$defs/numericExpression" },
       
{ "$dynamicRef": "#boolExpression" },
       
{ "$ref": "#/$defs/temporalInstantExpression" }
     
]
   
},
   
"temporalInstantExpression": {
     
"oneOf": [
       
{ "$ref": "#/$defs/instantInstance" },
       
{ "$ref": "#/$defs/propertyRef" },
       
{ "$ref": "#/$defs/systemIdentifier" },
       
{ "$ref": "#/$defs/functionCall" },
       
{ "$ref": "#/$defs/conditionalExpression" }
     
]
   
},
   
"isLikePredicate": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [ "like" ]
       
},
       
"args": {
         
"$ref": "#/$defs/isLikeOperands"
       
}
     
}
   
},
   
"isLikeOperands": {
         
"type": "array",
         
"prefixItems": [
           
{ "$ref": "#/$defs/characterExpression" },
           
{ "$ref": "#/$defs/patternExpression" }
         
],
         
"additionalItems": false
   
},
   
"textOpPredicate": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [ "contains", "startsWith", "endsWith" ]
       
},
       
"args": {
         
"type": "array",
         
"prefixItems": [
           
{ "$ref": "#/$defs/characterExpression" },
           
{ "$ref": "#/$defs/characterExpression" }
         
],
         
"additionalItems": false
       
}
     
}
   
},
   
"patternExpression": {
     
"oneOf": [
       
{
         
"type": "object",
         
"required": [ "op", "args" ],
         
"properties": {
           
"op": { "type": "string", "enum": [ "casei" ] },
           
"args": {
              
"type": "array",
              
"items": { "$ref": "#/$defs/patternExpression" },
              
"minItems": 1,
              
"maxItems": 1
           
}
         
}
       
},
       
{
         
"type": "object",
         
"required": [ "op", "args" ],
         
"properties": {
           
"op": { "type": "string", "enum": [ "accenti" ] },
           
"args": {
              
"type": "array",
              
"items": { "$ref": "#/$defs/patternExpression" },
              
"minItems": 1,
              
"maxItems": 1
           
}
         
}
       
},
       
{ "type": "string" }
     
]
   
},
   
"isBetweenPredicate": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": { "type": "string", "enum": [ "between" ] },
       
"args": { "$ref": "#/$defs/isBetweenOperands" }
     
}
   
},
   
"isBetweenOperands": {
     
"type": "array",
     
"minItems": 3,
     
"maxItems": 3,
     
"items": {
       
"$ref": "#/$defs/numericExpression"
     
},
     
"additionalItems": false
   
},
   
"numericExpression": {
     
"oneOf": [
       
{ "$ref": "#/$defs/arithmeticExpression" },
       
{ "$ref": "#/$defs/bitwiseLogical" },
       
{ "$ref": "#/$defs/bitwiseShift" },
       
{ "$ref": "#/$defs/bitwiseNot" },
       
{ "type": "number" },
       
{ "$ref": "#/$defs/propertyRef" },
       
{ "$ref": "#/$defs/systemIdentifier" },
       
{ "$ref": "#/$defs/functionCall" },
       
{ "$ref": "#/$defs/conditionalExpression" }
     
]
   
},
   
"isInListPredicate": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [ "in" ]
       
},
       
"args": {
         
"$ref": "#/$defs/inListOperands"
       
}
     
}
   
},
   
"inListOperands": {
     
"type": "array",
     
"prefixItems": [
       
{
         
"$ref": "#/$defs/scalarExpression"
       
},
       
{
         
"type": "array",
         
"items": {
           
"$ref": "#/$defs/scalarExpression"
         
}
       
}
     
],
     
"additionalItems": false
   
},
   
"isNullPredicate": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [ "isNull" ]
       
},
       
"args": {
         
"$ref": "#/$defs/isNullOperand"
       
}
     
}
   
},
   
"isNullOperand": {
     
"oneOf": [
       
{ "$ref": "#/$defs/characterExpression" },
       
{ "$ref": "#/$defs/numericExpression" },
       
{ "$dynamicRef": "#boolExpression" },
       
{ "$ref": "#/$defs/geomExpression" },
       
{ "$ref": "#/$defs/temporalExpression" }
     
]
   
},
   
"spatialPredicate": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [
           
"s_contains",
           
"s_crosses",
           
"s_disjoint",
           
"s_equals",
           
"s_intersects",
           
"s_overlaps",
           
"s_touches",
           
"s_within",
           
"s_covers",
           
"s_coveredBy"
         
]
       
},
       
"args": { "$ref": "#/$defs/spatialOperands" }
     
}
   
},
   
"spatialOperands": {
     
"type": "array",
     
"prefixItems": [
       
{ "$ref": "#/$defs/geomExpression" },
       
{ "$ref": "#/$defs/geomExpression" }
     
],
     
"additionalItems": false
   
},
   
"geomExpression": {
     
"oneOf": [
       
{ "$ref": "#/$defs/spatialInstance" },
       
{ "$ref": "#/$defs/propertyRef" },
       
{ "$ref": "#/$defs/systemIdentifier" },
       
{ "$ref": "#/$defs/functionCall" },
       
{ "$ref": "#/$defs/conditionalExpression" }
     
]
   
},
   
"temporalPredicate": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [
           
"t_after",
           
"t_before",
           
"t_contains",
           
"t_disjoint",
           
"t_during",
           
"t_equals",
           
"t_finishedBy",
           
"t_finishes",
           
"t_intersects",
           
"t_meets",
           
"t_metBy",
           
"t_overlappedBy",
           
"t_overlaps",
           
"t_startedBy",
           
"t_starts"
         
]
       
},
       
"args": { "$ref": "#/$defs/temporalOperands" }
     
}
   
},
   
"temporalOperands": {
     
"type": "array",
     
"prefixItems": [
       
{ "$ref": "#/$defs/temporalExpression" },
       
{ "$ref": "#/$defs/temporalExpression" }
     
],
     
"additionalItems": false
   
},
   
"temporalExpression": {
     
"oneOf": [
       
{ "$ref": "#/$defs/temporalInstance" },
       
{ "$ref": "#/$defs/propertyRef" },
       
{ "$ref": "#/$defs/systemIdentifier" },
       
{ "$ref": "#/$defs/functionCall" },
       
{ "$ref": "#/$defs/conditionalExpression" }
     
]
   
},
   
"arrayPredicate": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [
           
"a_containedBy",
           
"a_contains",
           
"a_equals",
           
"a_overlaps"
         
]
       
},
       
"args": { "$ref": "#/$defs/arrayArguments" }
     
}
   
},
   
"arrayArguments": {
     
"type": "array",
     
"minItems": 2,
     
"maxItems": 2,
     
"items": {
       
"oneOf": [
         
{ "$ref": "#/$defs/array" },
         
{ "$ref": "#/$defs/propertyRef" },
         
{ "$ref": "#/$defs/systemIdentifier" },
         
{ "$ref": "#/$defs/functionCall" },
         
{ "$ref": "#/$defs/conditionalExpression" }
       
]
     
}
   
},
   
"arrayExpression": {
     
"type": "array",
     
"items": {
       
"oneOf": [
         
{ "$ref": "#/$defs/array" },
         
{ "$ref": "#/$defs/propertyRef" },
         
{ "$ref": "#/$defs/systemIdentifier" },
         
{ "$ref": "#/$defs/functionCall" },
         
{ "$ref": "#/$defs/conditionalExpression" }
       
]
     
}
   
},
   
"array": {
     
"type": "array",
     
"items": {
       
"oneOf": [
         
{ "$ref": "#/$defs/characterExpression" },
         
{ "$ref": "#/$defs/numericExpression" },
         
{ "$dynamicRef": "#boolExpression" },
         
{ "$ref": "#/$defs/geomExpression" },
         
{ "$ref": "#/$defs/temporalExpression" },
         
{ "$ref": "#/$defs/array" }
       
]
     
}
   
},
   
"arithmeticExpression": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [ "+", "-", "*", "/", "^" ]
       
},
       
"args": {
         
"$ref": "#/$defs/arithmeticOperands"
       
}
     
}
   
},
   
"arithmeticOperands": {
     
"type": "array",
     
"minItems": 2,
     
"maxItems": 2,
     
"items": {
       
"oneOf": [
         
{ "$ref": "#/$defs/arithmeticExpression" },
         
{ "$ref": "#/$defs/bitwiseLogical" },
         
{ "$ref": "#/$defs/bitwiseShift" },
         
{ "$ref": "#/$defs/bitwiseNot" },
         
{ "$ref": "#/$defs/propertyRef" },
         
{ "$ref": "#/$defs/systemIdentifier" },
         
{ "$ref": "#/$defs/functionCall" },
         
{ "$ref": "#/$defs/conditionalExpression" },
         
{ "type": "number" }
       
]
     
}
   
},
   
"hexNumber": {
      
"type": "string",
      
"pattern": "^([a-fA-F0-9])+"
   
},
   
"bitwiseLogical": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [ "bitAnd", "bitOr", "bitXor" ]
       
},
       
"args": {
           
"type": "array",
           
"minItems": 2,
           
"maxItems": 2,
           
"items": {
             
"$ref": "#/$defs/bitwiseOperand"
           
}
       
}
     
}
   
},
   
"bitwiseNot": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [ "bitNot" ]
       
},
       
"args": {
           
"type": "array",
           
"minItems": 1,
           
"maxItems": 1,
           
"items": {
             
"$ref": "#/$defs/bitwiseOperand"
           
}
       
}
     
}
   
},
   
"bitwiseShift": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": {
         
"type": "string",
         
"enum": [ "<<", ">>" ]
       
},
       
"args": {
           
"type": "array",
           
"minItems": 2,
           
"maxItems": 2,
           
"items": {
             
"$ref": "#/$defs/bitwiseOperand"
           
}
       
}
     
}
   
},
   
"bitwiseOperand": {
       
"oneOf": [
         
{ "$ref": "#/$defs/arithmeticExpression" },
         
{ "$ref": "#/$defs/bitwiseLogical" },
         
{ "$ref": "#/$defs/bitwiseShift" },
         
{ "$ref": "#/$defs/bitwiseNot" },
         
{ "$ref": "#/$defs/propertyRef" },
         
{ "$ref": "#/$defs/systemIdentifier" },
         
{ "$ref": "#/$defs/functionCall" },
         
{ "$ref": "#/$defs/conditionalExpression" },
         
{ "type": "integer" },
         
{ "$ref": "#/$defs/hexNumber" }
       
]
   
},
   
"propertyRef": {
     
"type": "object",
     
"required": [ "property" ],
     
"properties": {
       
"property": { "type": "string" }
     
}
   
},
   
"casei": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": { "type": "string", "enum": [ "casei" ] },
       
"args": {
          
"type": "array",
          
"items": { "$ref": "#/$defs/characterExpression" },
          
"minItems": 1,
          
"maxItems": 1
       
}
     
}
   
},
   
"accenti": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": { "type": "string", "enum": [ "accenti" ] },
       
"args": {
          
"type": "array",
          
"items": { "$ref": "#/$defs/characterExpression" },
          
"minItems": 1,
          
"maxItems": 1
       
}
     
}
   
},
   
"lowerUpperCase": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
        
"op": {
          
"type": "string",
          
"enum": [ "lowerCase", "upperCase" ]
        
},
        
"args": {
          
"type": "array",
          
"items": { "$ref": "#/$defs/characterExpression" },
          
"minItems": 1,
          
"maxItems": 1
        
}
     
}
   
},
   
"concatenate": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties":
     
{
        
"op": {
          
"type": "string",
          
"enum": [ "concatenate" ]
        
},
        
"args": {
          
"type": "array",
          
"items": { "$ref": "#/$defs/characterExpression" },
          
"minItems": 2
        
}
     
}
   
},
   
"substitute": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties":
     
{
        
"name": {
          
"type": "string",
          
"enum": [ "substitute" ]
        
},
        
"args": {
          
"type": "array",
          
"items": { "$ref": "#/$defs/characterExpression" },
          
"minItems": 3,
          
"maxItems": 3
        
}
     
}
   
},
   
"format": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties":
     
{
        
"name": {
          
"type": "string",
          
"enum": [ "format" ]
        
},
        
"args": {
          
"type": "array",
          
"items": {
            
"oneOf": [
              
{ "$ref": "#/$defs/characterExpression" },
              
{ "$ref": "#/$defs/numericExpression" },
              
{ "$dynamicRef": "#boolExpression" },
              
{ "$ref": "#/$defs/geomExpression" },
              
{ "$ref": "#/$defs/temporalExpression" },
              
{ "$ref": "#/$defs/array" }
            
]
          
},
          
"prefixItems": [
            
{ "$ref": "#/$defs/characterExpression" }
          
],
          
"minItems": 1
        
}
     
}
   
},
   
"characterExpression": {
     
"oneOf": [
       
{ "$ref": "#/$defs/casei" },
       
{ "$ref": "#/$defs/accenti" },
       
{ "$ref": "#/$defs/lowerUpperCase" },
       
{ "$ref": "#/$defs/concatenate" },
       
{ "$ref": "#/$defs/substitute" },
       
{ "$ref": "#/$defs/format" },
       
{ "type": "string" },
       
{ "$ref": "#/$defs/propertyRef" },
       
{ "$ref": "#/$defs/systemIdentifier" },
       
{ "$ref": "#/$defs/functionCall" },
       
{ "$ref": "#/$defs/conditionalExpression" }
     
]
   
},
   
"geometryManipulationBinary": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties":
     
{
        
"name": {
          
"type": "string",
          
"enum": [ "s_intersection", "s_union", "s_difference", "s_symDifference" ]
        
},
        
"args": {
          
"type": "array",
          
"items": { "$ref": "#/$defs/spatialInstance" },
          
"minItems": 2,
          
"maxItems": 2
        
}
     
}
   
},
   
"geometryManipulationUnary": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties":
     
{
        
"name": {
          
"type": "string",
          
"enum": [ "s_convexHull", "s_envelope" ]
        
},
        
"args": {
          
"type": "array",
          
"items": { "$ref": "#/$defs/spatialInstance" },
          
"minItems": 1,
          
"maxItems": 1
        
}
     
}
   
},
   
"geometryBuffer": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties":
     
{
        
"name": {
          
"type": "string",
          
"enum": [ "s_buffer" ]
        
},
        
"args": {
          
"type": "array",
          
"prefixItems": [
            
{ "$ref": "#/$defs/spatialInstance" },
            
{ "$ref": "#/$defs/numericExpression" }
          
],
          
"minItems": 2,
          
"maxItems": 2
        
}
     
}
   
},
   
"conditionalExpression": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": { "type": "string", "enum": [ "?:" ] },
       
"args": {
         
"type": "array",
         
"minItems": 3,
         
"maxItems": 3,
         
"prefixItems": [
            
{ "$dynamicRef": "#boolExpression" },
            
{ "$ref": "#/$defs/anyExpression" }
         
]
       
}
     
}
   
},
   
"functionCall": {
     
"type": "object",
     
"required": [ "op", "args" ],
     
"properties": {
       
"op": { "type": "string" },
       
"args": {
         
"type": "array",
         
"items": {
           
"oneOf": [
             
{ "$ref": "#/$defs/characterExpression" },
             
{ "$ref": "#/$defs/numericExpression" },
             
{ "$dynamicRef": "#boolExpression" },
             
{ "$ref": "#/$defs/geomExpression" },
             
{ "$ref": "#/$defs/temporalExpression" },
             
{ "$ref": "#/$defs/array" }
           
]
         
}
       
}
     
}
   
},
   
"scalarLiteral": {
     
"oneOf": [
       
{ "type": "string" },
       
{ "type": "number" },
       
{ "type": "boolean" },
       
{ "$ref": "#/$defs/instantInstance" }
     
]
   
},
   
"spatialInstance": {
     
"oneOf": [
       
{ "$ref": "#/$defs/geometryManipulationBinary" },
       
{ "$ref": "#/$defs/geometryManipulationUnary" },
       
{ "$ref": "#/$defs/geometryBuffer" }
     
]
   
},
   
"temporalInstance": {
     
"oneOf": [
       
{ "$ref": "#/$defs/instantInstance" },
       
{ "$ref": "#/$defs/intervalInstance" }
     
]
   
},
   
"instantInstance": {
     
"oneOf": [
       
{ "$ref": "#/$defs/dateInstant" },
       
{ "$ref": "#/$defs/timestampInstant" }
     
]
   
},
   
"dateInstant": {
     
"type": "object",
     
"required": [ "date" ],
     
"properties": {
       
"date": { "$ref": "#/$defs/dateString" }
     
}
   
},
   
"timestampInstant": {
     
"type": "object",
     
"required": [ "timestamp" ],
     
"properties": {
       
"timestamp": { "$ref": "#/$defs/timestampString" }
     
}
   
},
   
"instantString": {
     
"oneOf": [
       
{ "$ref": "#/$defs/dateString" },
       
{ "$ref": "#/$defs/timestampString" }
     
]
   
},
   
"dateString": {
     
"type": "string",
     
"format": "date"
   
},
   
"timestampString": {
     
"type": "string",
     
"format": "date-time"
   
},
   
"intervalInstance": {
     
"type": "object",
     
"required": [ "interval" ],
     
"properties": {
       
"interval": { "$ref": "#/$defs/intervalArray" }
     
}
   
},
   
"intervalArray": {
     
"type": "array",
     
"minItems": 2,
     
"maxItems": 2,
     
"items": {
       
"oneOf": [
         
{ "$ref": "#/$defs/instantString" },
         
{ "type": "string", "enum": [ ".." ] },
         
{ "$ref": "#/$defs/propertyRef" },
         
{ "$ref": "#/$defs/systemIdentifier" },
         
{ "$ref": "#/$defs/functionCall" },
         
{ "$ref": "#/$defs/conditionalExpression" }
       
]
     
}
   
}
 
}
}

Listing

17.2.  Requirements

17.2.1.  JSON Styles and Symbology

Requirements class 20: JSON Styles and Symbology

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/json
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

18.  Requirements Class “Cartographic Symbology Cascading Style Sheets”

18.1.  Overview

This requirements class defines an encoding for the Styles and Symbology Logical Model inspired from Web Cascading Style Sheets (CSS) and other CSS-like cartographic symbology encodings. The primary objective of this encoding is expressiveness so as to facilitate hand-edition by cartographers. Parsing this encoding requires a custom parser.

18.1.1.  Cascading Style Sheets

A style is encoded as a series of styling rules into a style sheet document. Symbolizer properties set further down in rules override those set by rules at the same level apearing earlier (higher up).

It is also possible to include another style sheet using the .include directive followed by a relative path enclosed within single quotes (' '), separated by a space e.g., .include '../baseStyle.cscss'. The include directive is replaced by the content of that file in a pre-processing step in a recursive manner, so that style sheets can be cascaded.

Because later rules allow to override earlier ones, this cascading allows to apply for example:

  • run-time styling preferences over default user styling,

  • user styling preferences over default application styling,

  • application styling preferences over default data provider styling.

18.1.2.  Comments

A style sheet can also contain comments either using C-style multi-line comments (between /* and */) or C++-style single-line comments (starting with //).

18.1.3.  Styling Rules and Symbolizers

A styling rule applies zero or more symbolizer properties if its Selector is evaluated to true. A styling rule may also include nested rules that are only evaluated when the parent rule itself is selected. Symbolizer properties set within a nested rule override symbolizer properties set in the parent rule. It is also possible to override only a portion of a property by assigning a value to member of an object, or an element of an array.

The grammar for specifying a rule in this encoding is:

[<selector>]* ‘{’ [<symbolizer/>assignment>]* [<nested>]* ‘}’</nested></selector>

The grammar for a symbolizer property assignment is:

<symbolizer/>name> [’.’ <member> | ‘[’ </member>

18.1.4.  Selectors

A selector is either:

  • an expression as described in the section below (combined together as a logical AND),

  • or a short-hand form for selecting a data layer (combined between them as a logical OR, but combined with other selectors as a logical AND):

<data layer name>

18.1.5.  Expressions

18.1.5.1.  CQL2-Text encoding

Whether in Selectors or values of property symbolizers, Expressions are encoded using CQL2-Text. However, a number of extensions are introduced to cover the full range of capabilities defined by the styling and symbology conceptual model.

The first such extension is that in the context of a symbolizer property value, expressions are not limited to boolean predicates being evaluated as true or false, but can return any type of values such as numerical, text, or complex values, including geometry.

18.1.5.2.  Instance expressions

The concept of an object instance is introduced, with the grammar:

<Class Name> ‘(’ <member initializer list> ‘)’.

This corresponds somewhat to CQL2 constructs for temporal intervals and WKT geometry for example,

  • POLYGON( (0 40, 10 40, 10 50, 0 50, 0 40) )

  • INTERVAL('2021-01-01T00:00:00Z','2021-12-31T23:59:59Z')

In the first example, POLYGON is the class name, and the array of coordinates is a list of a single member initializer. In the second second example, INTERVAL is the class name, and the start and end dates are a list of two member initializers.

In both of these examples, the members being initialized are implied from the order. Due to the heavy use of object instances in the symbology model, the ability to identify specific member to initialize is introduced. The syntax for doing so tries to be consistent with the overall CSS inspiration, and therefore the <member> ‘:’ value is used, and the ‘;’ is added as an alternative way to separate members in the initializer list. As examples, the above instantiations could also be written:</member>

  • POLYGON(rings: (0 40, 10 40, 10 50, 0 50, 0 40))

  • INTERVAL(start: '2021-01-01T00:00:00Z'; end: '2021-12-31T23:59:59Z')

Another capability introduced is the ability to infer the class from the expected type where the instance expression is used. For example, if a POLYGON object is assigned to a poly property expecting that object type, then the expression can be written simply as:

  • (rings: (0 40, 10 40, 10 50, 0 50, 0 40))

In both of these examples, the members being initialized are implied from the order.

When not all members of a class are initialized within an instantiation, a default value is inherited. Those default values are specified in a dedicated section below

NOTE:  CartoSym-CSS supports and recommends the use of { } for object instances, and of [ ] for arrays, but also supports ( ) in these contexts for compatibility with the CQL2-Text and WKT encodings. A CQL2-Text expression (including WKT geometry) can therefore be used directly as an expression in a selector or symbolizer parameter value. However, a CartoSym-CSS expression making use of the curly and/or square brackets will not be a valid CQL2 expression.

18.1.5.4.  Units of measure

The following abbreviations are used, following a value, to qualify it with a unit of measure. These are mainly used for UnitPoint coordinates, as well as with distance value such as those specified for Shape graphics e.g., the radius of a circle.

Table 66 — Units of measure abbreviations

UnitAbbreviationNotes
pixelspxDisplay unit; not dependent on display resolution
metersmReal-world unit (SI unit of length)
feetftReal-world unit (0.3048 m)
percentpcRelative value whose meaning depends on context e.g., Image’s hotSpot, scaling.
pointsptOne point is equal to 1/72 inch (0.3528 mm).
ememOne em is equal to the target’s selected or default font point size.
screenInchesinchDisplay unit (25.4 mm); see OGC API — Maps “Display Resolution” requirements class (mm-per-pixel) which defaults to 0.28 mm/pixel (~90.7142857 pixels/inch).
screenCMcmDisplay unit (10 mm); see OGC API — Maps “Display Resolution” requirements class (mm-per-pixel) which defaults to 0.28 mm/pixel (0.028 cm/pixel).
screenMMmmDisplay unit; see OGC API — Maps “Display Resolution” requirements class (mm-per-pixel) which defaults to 0.28 mm/pixel.
(none)For relative values like scaling, 100 times less than if pc is specified. For screen-space objects, defaults to pixels.

18.1.5.5.  Conditional expressions

As an extension to CQL2-Text, this encoding adds support for conditional expressions using the grammar:

<if-expression> ‘?’ <then-expression> ‘:’ <else-expression>

18.1.5.6.  Enumeration values

As an extension to CQL2-Text, this encoding supports the concept of enumeration values, which do not need to be enclosed in single quotes. For compatibility with CQL2, the same identifier enclosed within single quotes is considered equivalent.

Enumeration values must conform to the CQL2 identifier grammar production rule, but may not be enclosed within double-quotes.

In a context where an enumeration is expected, the enumeration value takes precedence over an identifier that may be resolved by the same name. In order to explicitly refer to the identifier, the identifier can be enclosed in double-quotes.

18.1.5.7.  Colors

Color values can be expressed using any of the forms allowed for instantiations, or using a tuple:

  • Color(255, 100, 50)

  • Color{255, 100, 50}

  • Color(r: 255, g: 100, b: 50)

  • Color{r: 255, g: 100, b: 50}

  • {255, 100, 50}

  • {r: 255; g: 100; b: 50;}

  • 255 100 50

Colors can also be expressed as a hexadecimal value prefixed by a # symbol, as in Web CSS:

  • #FF6432

Finally, colors can also be expressed as an enumeration value for named web colors:

  • red

  • 'red'

Table 67 — Named web color enumeration

NameHexadecimalValue (r, g, b)
black0x0000000, 0, 0
dimGray0x696969105, 105, 105
dimGrey0x696969105, 105, 105
gray0x808080128, 128, 128
grey0x808080128, 128, 128
darkGray0xa9a9a9169, 169, 165
darkGrey0xa9a9a9169, 169, 165
silver0xc0c0c0192, 192, 192
lightGray0xd3d3d3211, 211, 211
lightGrey0xd3d3d3211, 211, 211
gainsboro0xdcdcdc220, 220, 220
whiteSmoke0xf5f5f5245, 245, 245
white0xffffff255, 255, 255
rosyBrown0xbc8f8f188, 143, 143
indianRed0xcd5c5c205, 92, 92
brown0xa52a2a165, 42, 42
fireBrick0xb22222178, 34, 34
lightCoral0xf08080240, 128, 128
maroon0x800000128, 0, 0
darkRed0x8b0000139, 0, 0
red0xff0000255, 0, 0
snow0xfffafa255, 250, 250
mistyRose0xffe4e1255, 228, 225
salmon0xfa8072250, 128, 114
tomato0xff6347255, 99, 71
darkSalmon0xe9967a233, 150, 122
coral0xff7f50255, 127, 80
orangeRed0xff4500255, 69, 0
lightSalmon0xffa07a255, 160, 122
sienna0xa0522d160, 82, 45
seaShell0xfff5ee255, 245, 238
chocolate0xd2691e210, 105, 30
saddleBrown0x8b4513139, 69, 19
sandyBrown0xf4a460244, 164, 96
peachPuff0xffdab9255, 218, 185
peru0xcd853f205, 133, 63
linen0xfaf0e6250, 240, 230
bisque0xffe4c4255, 228, 196
darkOrange0xff8c00255, 140, 0
burlyWood0xdeb887222, 184, 135
tan0xd2b48c210, 180, 140
antiqueWhite0xfaebd7250, 235, 215
navajoWhite0xffdead255, 222, 173
blanchedAlmond0xffebcd255, 235, 205
papayaWhip0xffefd5255, 239, 213
moccasin0xffe4b5255, 228, 181
orange0xffa500255, 165, 0
wheat0xf5deb3245, 222, 179
oldLace0xfdf5e6253, 245, 230
floralWhite0xfffaf0255, 250, 240
darkGoldenrod0xb8860b184, 134, 11
goldenrod0xdaa520218, 165, 32
cornsilk0xfff8dc255, 248, 220
gold0xffd700255, 215, 0
khaki0xf0e68c240, 230, 140
lemonChiffon0xfffacd255, 250, 205
paleGoldenrod0xeee8aa238, 232, 170
darkKhaki0xbdb76b189, 183, 107
beige0xf5f5dc245, 245, 220
lightGoldenRodYellow0xfafad2250, 250, 210
olive0x808000128, 128, 0
yellow0xffff00255, 255, 0
lightYellow0xffffe0255, 255, 224
ivory0xfffff0255, 255, 240
oliveDrab0x6b8e23107, 142, 35
yellowGreen0x9acd32154, 205, 50
darkOliveGreen0x556b2f85, 107, 47
greenYellow0xadff2f173, 255, 47
chartreuse0x7fff00127, 255, 0
lawnGreen0x7cfc00124, 252, 0
darkSeaGreen0x8fbc8f143, 188, 139
forestGreen0x228b2234, 139, 34
limeGreen0x32cd3250, 205, 50
lightGreen0x90ee90144, 238, 144
paleGreen0x98fb98152, 251, 152
darkGreen0x0064000, 100, 0
green0x0080000, 128, 0
lime0x00ff000, 255, 0
honeyDew0xf0fff0240, 255, 240
seaGreen0x2e8b5746, 139, 87
mediumSeaGreen0x3cb37160, 179, 113
springGreen0x00ff7f0, 255, 127
mintCream0xf5fffa245, 255, 250
mediumSpringGreen0x00fa9a0, 250, 154
mediumAquaMarine0x66cdaa102, 205, 170
aquamarine0x7fffd4127, 255, 212
turquoise0x40e0d064, 224, 208
lightSeaGreen0x20b2aa32, 178, 170
mediumTurquoise0x48d1cc72, 209, 204
darkSlateGray0x2f4f4f47, 79, 79
darkSlateGrey0x2f4f4f47, 79, 79
paleTurquoise0xafeeee175, 238, 238
teal0x0080800, 128, 128
darkCyan0x008b8b0, 139, 139
aqua0x00ffff0, 255, 255
cyan0x00ffff0, 255, 255
lightCyan0xe0ffff224, 255, 255
azure0xf0ffff240, 255, 255
darkTurquoise0x00ced10, 206, 209
cadetBlue0x5f9ea095, 158, 160
powderBlue0xb0e0e6176, 224, 230
lightBlue0xadd8e6173, 216, 230
deepSkyBlue0x00bfff0, 191, 255
skyBlue0x87ceeb135, 206, 235
lightSkyBlue0x87cefa135, 206, 250
steelBlue0x4682b470, 130, 180
aliceBlue0xf0f8ff240, 248, 255
dodgerBlue0x1e90ff30, 144, 255
slateGray0x708090112, 128, 144
slateGrey0x708090112, 128, 144
lightSlateGray0x778899119, 136, 153
lightSlateGrey0x778899119, 136, 153
lightSteelBlue0xb0c4de176, 196, 222
cornflowerBlue0x6495ed100, 149, 237
royalBlue0x4169e165, 105, 225
midnightBlue0x19197025, 25, 112
lavender0xe6e6fa230, 230, 250
navy0x0000800, 0, 128
darkBlue0x00008b0, 0, 139
mediumBlue0x0000cd0, 0, 205
blue0x0000ff0, 0, 255
ghostWhite0xf8f8ff248, 248, 255
slateBlue0x6a5acd106, 90, 205
darkSlateBlue0x483d8b72, 61, 139
mediumSlateBlue0x7b68ee123, 104, 238
mediumPurple0x9370db147, 112, 219
blueViolet0x8a2be2138, 43, 226
indigo0x4b008275, 0, 130
darkOrchid0x9932cc153, 50, 204
darkViolet0x9400d3148, 0, 211
mediumOrchid0xba55d3186, 85, 211
thistle0xd8bfd8216, 191, 216
plum0xdda0dd221, 160, 221
violet0x40e0d0238, 130, 238
purple0x800080128, 0, 128
darkMagenta0x8b008b139, 0, 139
magenta0xff00ff255, 0, 255
fuschia0xff00ff255, 0, 255
orchid0xda70d6218, 112, 214
mediumVioletRed0xc71585199, 21, 133
deepPink0xff1493255, 20, 147
hotPink0xff69b4255, 155, 180
lavenderBlush0xfff0f5255, 240, 245
paleVioletRed0xdb7093219, 112, 147
crimson0xdc143c220, 20, 60
pink0xffc0cb255, 192, 203
lightPink0xffb6c1255, 182, 193

18.1.6.  Examples

Example — CSCSS Example encoding style using “Core” requirements class

 

.title 'Styling a land use layer'
.abstract 'Styling land use data with Style & Symbology Core'

Landuse[dataLayer.type = vector]
{
   visibility: false;

   [viz.sd < 200000 and viz.date > DATE('2020-01-01')]
   {
      visibility: true;
      opacity: 0.5;
      zOrder: 1;
   }
}

18.1.6.1.  Basic Vector Styling

Example 1 — CSCSS Example encoding style for polygon features using “Basic Vector Styling” requirements class

 

.title 'Styling polygon vector features'
.abstract 'Basic vector features styling (polygons)'

Landuse[dataLayer.type = vector and dataLayer.featuresGeometryDimensions = 2]
{
   // Do not show Landuse layer by default
   visibility: false;

   // Show land use if zoomed in more than 1:200,000 for data valid within visualization's selected time range
   [viz.sd < 200000 and validDate >= viz.timeInterval.start.date and validDate <= viz.timeInterval.end.date]
   {
      visibility: true;
      opacity: 0.8;
      zOrder: 1;
      fill: {color: gray; opacity: 0.5};
      stroke: {color: gray; width: 2.0 px; opacity: 1.0};

      // Select different fill and stroke color based on FunctionCode property
      [FunctionCode = 'parking']
      {
         fill.color: darkGray;
         stroke.color: #202020;
      }
      [FunctionCode = 'park']
      {
         fill.color: darkGreen;
         stroke.color: green;
      }
      [FunctionCode = 'commercial']
      {
         fill.color: lightGray;
         stroke.color: lightGray;
      }

      // If zoomed in more than 1:10,000
      [viz.sd < 10000]
      {
         // Change stroke width to 4 pixels
         stroke.width: 4.0 px;
         // Add a text marker (positioned at centroid + horizontal offset) showing FunctionTitle property
         marker: {elements: [
            Text(
               position: 20 0; // Offset 20 pixels to the right
               text: FunctionTitle;
               alignment: left top;
               font: {
                  face: 'Arial';
                  size: 14;
                  bold: true;
                  italic: true;
                  opacity: 1.0;
                  color: black;
               };
            )
         ]};
         // Add icons at centroid based on land use function code property
         [FunctionCode = 'parking']
         {
            marker.elements[1]:
               Image {
                  image: {uri: 'http://example.com/parkingIcon'; path: 'parkingIcon.png'; id: 'parking'; type: 'image/png'; ext: 'png'};
                  hotSpot: 50 pc 50 pc; tint: white; blackTint: blue; alphaThreshold: 0.1;
               };
         }
         [FunctionCode = 'park']
         {
            marker.elements[1]:
               Image {
                  image: {uri: 'http://example.com/park'; path: 'park.png'; id: 'park'; type: 'image/png'; ext: 'png'};
                  hotSpot: 50 pc 50 pc; tint: white; blackTint: blue; alphaThreshold: 0.1;
               };
         }
         [FunctionCode = 'commercial']
         {
            marker.elements[1]:
               Image {
                  image: {uri: 'http://example.com/commercial'; path: 'commercial.png'; id: 'commercial'; type: 'image/png'; ext: 'png'};
                  hotSpot: 50 pc 50 pc; tint: white; blackTint: blue; alphaThreshold: 0.1;
               };
         }
      }
   }
}

Example 2 — CSCSS Example encoding style for line features using “Basic Vector Styling” requirements class

 

.title 'Styling line vector features'
.abstract 'Basic vector features styling (lines)'

Roads[dataLayer.type = vector and dataLayer.featuresGeometryDimensions = 1]
{
   visibility: false;

   [viz.sd < 200000 and validDate >= viz.timeInterval.start.date and validDate <= viz.timeInterval.end.date]
   {
      visibility: true;
      opacity: 0.8;
      zOrder: 2;
      stroke: {color: gray; width: 5.0 px; opacity: 1.0};

      // If zoomed in more than 1:10,000
      [viz.sd < 10000]
      {
         // Change stroke width to 8 meters
         stroke.width: 8.0 m;
         // Add Dot at each segment end-point
         marker: { elements: [
            Dot {
               size: 10 m; // Alias for base Shape class stroke width
               color: white;
            }
         ] };
      }
   }
}

Example 3 — CSCSS Example encoding style for point features using “Basic Vector Styling” requirements class

 

.title 'Styling point vector features'
.abstract 'Basic vector features styling (points)'

Amenities[dataLayer.type = 'vector' and dataLayer.featuresGeometryDimensions = 0]
{
   visibility: false;

   [viz.sd < 200000 and validDate >= viz.timeInterval.start.date and validDate <= viz.timeInterval.end.date]
   {
      visibility: true;
      opacity: 0.5;
      zOrder: 3;

      // If zoomed in more than 1:10,000
      [viz.sd < 10000]
      {
         // Add a double-Dot marker (positioned at centroid)
         marker: { elements: [
            Dot {  // larger white dot underneath
               size: 10 px; // Alias for base Shape class stroke width
               alignment: center middle;
               color: white;
            },
            Dot {  // smaller orange dot in center
               size: 8 px; // Alias for base Shape class stroke width
               alignment: center middle;
               color: orange;
            }
         ]};
         [viz.sd < 5000]
         {
            // Add a Text graphic to Marker at 1:5000
            marker.elements[1]:
               Text {
                  position: 20 0; // Offset 20 pixels to the right
                  text: Name; // Name of Amenity
                  alignment: left middle;
                  font: {
                     face: 'Arial';
                     size: 12;
                     bold: false;
                     italic: false;
                     opacity: 1.0;
                     color: darkGray;
                  }
               };
         }
      }
   }
}

18.1.6.2.  Basic Coverage Styling

Example 1 — CSCSS Example encoding style rendering DEM with a color map using “Basic Coverage Styling” requirements class

 

.title 'DEM with color map'
.abstract 'Applying a color map to a Digital Elevation Model with Style & Symbology Basic Coverage Styling'

Elevation[dataLayer.type = coverage]
{
   visibility: false;

   [viz.sd < 200000]
   {
      visibility: true;
      opacity: 0.8;
      zOrder: 1;

      singleChannel: elevation; // Use elevation coverage field
      colorMap: [ 0 96 136 73, 900 226 219 167, 1300 252 197 117, 1900 254 168 134, 2500 250 250 250 ];
   }
}

Example 2 — CSCSS Example encoding style rendering sentinel-2 in natural color from 3 bands using “Basic Coverage Styling” requirements class

 

.title 'sentinel-2 natural color'
.abstract 'Styling a Sentinel-2A coverage with Style & Symbology Basic Coverage Styling'

"sentinel2-l2a"[dataLayer.type = coverage]
{
   visibility: false;

   [viz.sd < 200000]
   {
      visibility: true;
      opacity: 0.8;
      zOrder: 1;

      colorChannels: B04 B03 B02;
      alphaChannel: 1.0;
      [SCL=8] { alphaChannel: 0.5; }   // Reduce alpha channel value for medium cloud probability
      [SCL=9] { alphaChannel: 0.0; }   // Zero alpha channel value for high cloud probability
   }
}

18.1.6.3.  Arithmetic Operations (with Basic Coverage Styling)

Example — CSCSS Example encoding style rendering NDVI with color map using “Basic Coverage Styling” requirements class

 

.title 'sentinel-2 NDVI'
.abstract 'Styling a Sentinel-2A coverage for NDVI with Style & Symbology Basic Coverage Styling'

"sentinel2-l2a"[dataLayer.type = coverage]
{
   visibility: false;

   [viz.sd < 200000]
   {
      visibility: true;
      opacity: 0.8;
      zOrder: 1;

      singleChannel: (B08 - B04)/(B08 + B04);
      alphaChannel: 1.0;
      colorMap: [-1.0 saddleBrown,0.0 peru,0.2 goldenrod,0.5 olive,0.6 yellowGreen,0.8 greenYellow,1.0 lime];

      [SCL=8] { alphaChannel: 0.5; }   // Reduce alpha channel value for medium cloud probability
      [SCL=9] { alphaChannel: 0.0; }   // Zero alpha channel value for high cloud probability
   }
}

18.1.6.4.  Hill Shading

Example 1 — CSCSS Example encoding style rendering DEM with hill-shading and a color map using “Basic Coverage Styling” and “Hill Shading” requirements classes

 

.title 'hill-shaded DEM with color map'
.abstract 'Applying hill-shading and a color map to a Digital Elevation Model with Style & Symbology Basic Coverage Styling'

Elevation[dataLayer.type = coverage]
{
   visibility: false;

   [viz.sd < 200000]
   {
      visibility: true;
      opacity: 0.8;
      zOrder: 1;

      singleChannel: elevation; // Use elevation coverage field
      // This color map is mapped from elevation values
      colorMap: [0 96 136 73, 900 226 219 167, 1300 252 197 117, 1900 254 168 134, 2500 250 250 250];
      hillShading: {factor: 56; sun: {azimuth: 45.0; elevation: 60.0}};
   }
}

Example 2 — CSCSS Example encoding style rendering DEM with hill-shading using an opacity and shading intensity color map using “Basic Coverage Styling” and “Hill Shading” requirements classes

 

.title 'hill-shaded DEM with opacity and color map for shading intensity'
.abstract 'Applying hill-shading a color map to a Digital Elevation Model with Style & Symbology Basic Coverage Styling'

// This type of intensity-based hill shading can be overlaid on top of imagery or vector maps

Elevation[dataLayer.type = coverage]
{
   visibility: false;

   [viz.sd < 200000]
   {
      visibility: true;
      opacity: 0.8;
      zOrder: 1;

      singleChannel: elevation; // Use elevation coverage field
      hillShading: {
         factor: 56;
         sun: {azimuth: 45.0; elevation: 60.0};
         // These colors and opacity are mapped from the 0..1 shading intensity rather than elevation values
         colorMap : [0 black, 0.15 gray, 0.35 silver, 0.55 white];
         opacityMap: [0 0.75, 0.15 0.50, 0.35 0.25, 0.55 0.00];
      };
   }
}

18.1.7.  BNF token definitions

The following token definitions for ANTLR4 can be used to generate a lexer for the encoding.

 

lexer grammar CartoSymCSSLexer;

channels { WHITESPACE, COMMENTS }

LCBR: '{';
RCBR: '}';
DOT: '.';
SEMI: ';';
LSBR: '[';
RSBR: ']';
LPAR: '(';
RPAR: ')';
COMMA: ',';
EQ: '=';
LT: '<';
LTEQ: '<=';
GT: '>';
GTEQ: '>=';
IN: 'in';
NOT: 'not';
IS: 'is';
LIKE: 'like';
BETWEEN: 'between';
QUESTION: '?';
COLON: ':';
AND: 'and';
OR: 'or';
MUL: '*';
DIV: '/';
IDIV: 'div';
MOD: '%';
POW: '^';
MINUS: '-';
PLUS: '+';

// Numeric Literals

UNIT:
   'px' |
   'm' |
   'ft' |
   'pc' |
   'pt' |
   'em' |
   'inch' |
   'cm' |
   'mm';

HEX_LITERAL :
    '#' ([0-9] | [a-f] | [A-F])+;

NUMERIC_LITERAL :
        ( [0-9]+ ('.' ([0-9]+)? )? |
        '.' [0-9]+ )
    ('E' ('+'|'-')? [0-9]+)?;

// Character Literals

fragment WHITESPACE:  '\u0009'  // Character tabulation
           | '\u000A'  // Line feed
           | '\u000B'  // Line tabulation
           | '\u000C'  // Form feed
           | '\u000D'  // Carriage return
           | '\u0020'  // Space
           | '\u0085'  // Next line
           | '\u00A0'  // No-break space
           | '\u1680'  // Ogham space mark
           | '\u2000'  // En quad
           | '\u2001'  // Em quad
           | '\u2002'  // En space
           | '\u2003'  // Em space
           | '\u2004'  // Three-per-em space
           | '\u2005'  // Four-per-em space
           | '\u2006'  // Six-per-em space
           | '\u2007'  // Figure space
           | '\u2008'  // Punctuation space
           | '\u2009'  // Thin space
           | '\u200A'  // Hair space
           | '\u2028'  // Line separator
           | '\u2029'  // Paragraph separator
           | '\u202F'  // Narrow no-break space
           | '\u205F'  // Medium mathematical space
           | '\u3000'; // Ideographic space

fragment CHARACTER : CHARACTER_NODLBQUOTE | '"' | ESCAPED_QUOTE;
fragment CHARACTER_NODLBQUOTE : ALPHA_NODBLQUOTE | [0-9] | WHITESPACE;

CHARACTER_LITERAL : '\'' CHARACTER* '\'';

fragment ESCAPED_QUOTE :'\'\'' | '\\\'';

fragment ALPHA_NODBLQUOTE : '\u0007'..'\u0008'     // bell, bs
      | '\u0021'               // !
      | '\u0023'..'\u0026'     // #, $, %, &
      | '\u0028'..'\u002F'     // (, ), *, +, comma, -, ., /
      | '\u003A'..'\u0084'     // --+
      | '\u0086'..'\u009F'     //   |
      | '\u00A1'..'\u167F'     //   |
      | '\u1681'..'\u1FFF'     //   |
      | '\u200B'..'\u2027'     //   +-> :,;,<,=,>,?,@,A-Z,[,\,],^,_,`,a-z,...
      | '\u202A'..'\u202E'     //   |
      | '\u2030'..'\u205E'     //   |
      | '\u2060'..'\u2FFF'     //   |
      | '\u3001'..'\uD7FF'     // --+
      | '\uE000'..'\uFFFD'     // See (CQL2) note 8.
      ;

// Identifiers

IDENTIFIER: UNQUOTED_IDENTIFIER | '"' CHARACTER_NODLBQUOTE* '"';

fragment UNQUOTED_IDENTIFIER: IDENTIFIER_START IDENTIFIER_PART*;

fragment IDENTIFIER_PART: IDENTIFIER_START
               | [0-9]                  // 0-9
               | '\u0300'..'\u036F'     // combining and diacritical marks
               | '\u203F'..'\u2040';    // ‿ and ⁀

fragment IDENTIFIER_START:
                  '\u005F'            // underscore
                | '\u0041'..'\u005A'   // A-Z
                | '\u0061'..'\u007A'   // a-z
                | '\u00C0'..'\u00D6'   // À-Ö Latin-1 Supplement Letters
                | '\u00D8'..'\u00F6'   // Ø-ö Latin-1 Supplement Letters
                | '\u00F8'..'\u02FF'   // ø-ÿ Latin-1 Supplement Letters
                | '\u0370'..'\u037D'   // Ͱ-ͽ Greek and Coptic (without ';')
                | '\u037F'..'\u1FFE'   // See (CQL2) note 1.
                | '\u200C'..'\u200D'   // zero width non-joiner and joiner
                | '\u2070'..'\u218F'   // See (CQL2) note 2.
                | '\u2C00'..'\u2FEF'   // See (CQL2) note 3.
                | '\u3001'..'\uD7FF'   // See (CQL2) note 4.
                | '\uF900'..'\uFDCF'   // See (CQL2) note 5.
                | '\uFDF0'..'\uFFFD'   // See (CQL2) note 6.
                ;

COMMENT
    : '/*' .*? '*/' -> channel(COMMENTS)
    ;

LINE_COMMENT
    : '//' ~[\r\n]* -> channel(COMMENTS)
    ;

WS : [ \t\r\n]+ -> channel(WHITESPACE); // skip spaces, tabs, newlines

Listing

18.1.8.  BNF grammar definition

The following grammar for ANTLR4 can be used to generate a parser for the encoding.

 

parser grammar CartoSymCSSGrammar;
options { tokenVocab=CartoSymCSSLexer; }

///////////////////////////////
// High level style sheet rules
///////////////////////////////

styleSheet: metadata* stylingRuleList;

metadata:
    '.' IDENTIFIER CHARACTER_LITERAL;

stylingRuleList:
     stylingRule
   | stylingRuleList stylingRule;

stylingRule:
   ( selector )*
   LCBR
      (propertyAssignmentList SEMI)?
      stylingRuleList?
   RCBR;

selector:
     IDENTIFIER
   | LSBR expression RSBR ;

///////////////////////////////
// Expressions

idOrConstant:
     IDENTIFIER
   | expConstant;

tuple:
     idOrConstant idOrConstant
   | tuple idOrConstant;

expression:
     idOrConstant

   | expression DOT IDENTIFIER   // Member access

   | expString
   | expCall
   | expArray

   | expInstance

   | LPAR expression RPAR

   | expression LSBR expConstant RSBR  // Indexing

   // Operations
   | expression arithmeticOperatorExp expression
   | expression arithmeticOperatorMul expression
   | expression arithmeticOperatorAdd expression
   | expression binaryLogicalOperator expression
   | expression relationalOperator expression
   | expression betweenOperator expression AND expression
   | expression QUESTION expression COLON expression
   | unaryLogicalOperator expression
   | unaryArithmeticOperator expression

   | tuple
   ;

expConstant: NUMERIC_LITERAL UNIT? | HEX_LITERAL;

expString: CHARACTER_LITERAL;

///////////////////////////////
// Expressions: Instances

expInstance:
   IDENTIFIER?
   LCBR
      propertyAssignmentInferredList?
      SEMI?
   RCBR |
   IDENTIFIER
   LPAR
      propertyAssignmentInferredList?
      SEMI?
   RPAR
   ;

lhValue:
     IDENTIFIER
   | lhValue DOT IDENTIFIER
   | lhValue LSBR expConstant RSBR ;

propertyAssignment:
   lhValue COLON expression;

propertyAssignmentList:
     propertyAssignment
   | propertyAssignmentList SEMI propertyAssignment;

propertyAssignmentInferred:
     propertyAssignment
   | expression
   ;

propertyAssignmentInferredList:
     propertyAssignmentInferred
   | propertyAssignmentInferredList SEMI propertyAssignmentInferred
   | propertyAssignmentInferredList COMMA propertyAssignmentInferred
   ;

///////////////////////////////
// Expressions: Arrays

expArray:
     LSBR arrayElements? RSBR
   | LPAR arrayElements? RPAR;

arrayElements:
     expression
   | arrayElements COMMA expression ;

///////////////////////////////
// Expressions: Function calls

expCall: IDENTIFIER LPAR arguments RPAR ;

arguments:
   expression
   | arguments COMMA expression;

binaryLogicalOperator: AND | OR ;

unaryLogicalOperator: NOT ;

unaryArithmeticOperator: PLUS | MINUS;

arithmeticOperatorExp:
   POW;

arithmeticOperatorMul:
     MUL
   | DIV
   | IDIV
   | MOD;

arithmeticOperatorAdd:
     MINUS
   | PLUS
;

relationalOperator:
     EQ
   | LT
   | LTEQ
   | GT
   | GTEQ
   | IN
   | NOT IN
   | IS
   | IS NOT
   | LIKE
   | NOT LIKE;

betweenOperator:
     BETWEEN
   | NOT BETWEEN;

Listing

18.2.  Requirements

18.2.1.  Cartographic Symbology Cascading Style Sheets

Requirements class 21: Cascading Style Sheets

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/req/cscss
Target typeStyle encodings and Renderers
PrerequisiteRequirements class 1: http://www.opengis.net/spec/cartosym-1/2.0/req/core

Annex A
(normative)
Abstract Test Suite

A Symbology Encoding or Rendering Engine implementation shall satisfy at minimum the abstract tests of the “Core” conformance class to be conformant with this specification, and optionally the abstract tests of any number of additional conformance classes.

The root OGC URI identifier for the conformance classes of this Abstract Tests Suite is:

http://www.opengis.net/spec/cartosym-1/2.0/conf/

A.1.  Conformance Class “Core”

Conformance class A.1

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/conf/core
Subject Requirements Class “Core”
Target TypeEncoding
Rendering engine

Abstract test A.1

Identifier/conf/core/rules
RequirementRequirement 1: /req/core/rules
Test purpose

Validate the encoding of styling rules

Test method

Given:

When:

Then:

A.2.  Conformance Class “Basic Vector Features Styling”

Conformance class A.2

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/conf/vector
Subject Requirements Class “Basic Vector Features Styling”
Target TypeEncoding
Rendering engine

Abstract test A.2

Identifier/conf/vector/stroke
RequirementRequirement 26: /req/vector/stroke
Test purpose

Validate the encoding of a symbolizer stroke

Test method

Given:

When:

Then:

A.3.  Conformance Class “Basic Coverage Styling”

Conformance class A.3

Identifierhttp://www.opengis.net/spec/cartosym-1/2.0/conf/coverage
Subject Requirements Class “Basic Coverage Styling”
Target TypeEncoding
Rendering engine

Abstract test A.3

Identifier/conf/coverage/color-channels
RequirementRequirement 34: /req/coverage/color-channels
Test purpose

Validate the encoding of a symbolizer colorChannels

Test method

Given:

When:

Then:


Annex B
(informative)
Mapping of SLD/SE and notable vendor extensions to the Conceptual Model

This annex maps constructs of the OGC Styled Layer Descriptor (SLD) and Symbology Encoding (SE) 1.1 to the conceptual model and requirements classes defined in the Part 1 of this Standard, with the goal of facilitating conformance to this Standard for Rendering engines based on SLD/SE and writing conversion tools that can convert in either or both direction between SLD/SE and the two encodings defined in this Standard.

B.1.  Requirements Class “Core”

Table B.1 — Mapping of Styling Rules to SLD/SE constructs

ConstructSE Equivalent
StylingRule<Rule>
name<Name> inside <Rule>
selector<ogc:Filter>
symbolizer<PointSymbolizer>, <LineSymbolizer>, <PolygonSymbolizer>, <TextSymbolizer>, <RasterSymbolizer>
nestedRules<ogc:ElseFilter> provides limited support for one use case of nested rules

Table B.2 — Mapping of Symbolizers to SLD/SE constructs

ConstructSE Equivalent
visibility<MaxScaleDenominator>, <MinScaleDenominator>
opacity<Opacity> inside <RasterSymbolizer> (no global opacity for vector symbolizers)
zOrdersortBy and sortByGroup vendor options in GeoServer

Table B.3 — Mapping of Expressions to SLD/SE constructs

ConstructSE Equivalent
LiteralExpression<ogc:Literal> (see table below)
IdentifierExpression<ogc:PropertyName> for feature properties, <SourceChannelName> for raster fields, System Identifiers (see table below)
InstanceExpressionN/A
ArrayExpressionN/A
OperationExpressionComparison operators with optional logical operators (see table below)

Table B.4 — Mapping of System Identifiers Expressions to SLD/SE constructs

ConstructSE Equivalent
visualizationN/A
visualization.scaleDenominator<MaxScaleDenominator>, <MinScaleDenominator>
visualization.dateTimeN/A
visualization.dateN/A
visualization.timeOfDayN/A
visualization.timeIntervalN/A
visualization.passOrder of <FeatureTypeStyles> in a <UserStyle> (sortBy and sortByGroup vendor options in GeoServer for additional control)
feature.passOrder of symbolizers in the <Rule>
dataLayerN/A
dataLayer.identifier<NamedLayer> and <Name>
dataLayer.typeN/A

Table B.5 — Mapping of Operators to SLD/SE constructs

ConstructSE Equivalent
RelationalOperatorComparison operators (<ogc:PropertyIsEqualTo>, <ogc:PropertyIsLessThan>, etc.)
LogicOperatorLogical operators (<ogc:And>, <ogc:Or>, <ogc:Not>)

Table B.6 — Mapping of Literal Expressions to SLD/SE constructs

ConstructSE Equivalent
TextLiteraltext directly in <ogc:Literal>
BoolLiteraltrue or false in <ogc:Literal>
NullLiteral<PropertyIsNull> when testing for null values
IntegerLiteralinteger value directly in <ogc:Literal>
RealLiteraldouble value inside <ogc:Literal>
ArrayLiteralN/A
InstanceLiteralN/A

Table B.7 — Mapping of Relational Operators to SLD/SE constructs

ConstructSE Equivalent
equal<ogc:PropertyIsEqualTo>
notEqual<ogc:PropertyIsNotEqualTo>
is (null)
lesser<ogc:PropertyIsLessThan>
greater<ogc:PropertyIsGreaterThan>
lesserEqual<ogc:PropertyIsLessThanOrEqualTo>
greaterEqual<ogc:PropertyIsGreaterThanOrEqualTo>

Table B.8 — Mapping of the “Core” requirements class to SLD/SE constructs

ConstructSE Equivalent
Styling Rules<Rule>
name<Name> inside <Rule>
Symbolizer<PointSymbolizer>, <LineSymbolizer>, <PolygonSymbolizer>, <TextSymbolizer>, <RasterSymbolizer>
Symbolizer opacity<Opacity> inside <RasterSymbolizer> (no global opacity for vector symbolizers)
Selector<ogc:Filter>
nestedRules<ogc:ElseFilter> provides limited support for one use case of nested rules
Expression
LiteralExpression<ogc:Literal>
IdentifierExpression<ogc:PropertyName> for feature properties, <SourceChannelName> for raster fields
InstanceExpressionN/A
ArrayExpressionN/A
OperationExpressionComparison operators (<ogc:PropertyIsEqualTo>, <ogc:PropertyIsLessThan>, etc.) with optional logical operators (<ogc:And>, <ogc:Or>, <ogc:Not>)
Operation Expressions
RelationalOperatorComparison operators (<ogc:PropertyIsEqualTo>, <ogc:PropertyIsLessThan>, etc.)
LogicOperatorLogical operators (<ogc:And>, <ogc:Or>, <ogc:Not>)

Table B.9 — Mapping of the “Sytem Identifiers Expressions” requirements class to SLD/SE constructs

ConstructSE Equivalent
visualizationN/A
visualization.scaleDenominator<MaxScaleDenominator>, <MinScaleDenominator>
visualization.dateTimeN/A
visualization.dateN/A
visualization.timeOfDayN/A
visualization.passOrder of <FeatureTypeStyles> in a <UserStyle> (sortBy and sortByGroup vendor options in GeoServer for additional control)
feature.passOrder of symbolizers in the <Rule>
dataLayerN/A
dataLayer.identifier<NamedLayer> and <Name>
dataLayer.typeN/A

Example — SLD Example encoding style using “Core” requirements class

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<StyledLayerDescriptor version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:se="http://www.opengis.net/se">
   <NamedLayer>
      <Name>Landuse</Name>
      <UserStyle>
         <Name>Styling a land use layer</Name>
         <Abstract>Styling land use data with Style &amp; Symbology Core</Abstract>
         <FeatureTypeStyle>
            <Rule>
               <Name>parking</Name>
               <Title>parking</Title>
               <ogc:Filter>
                  <ogc:PropertyIsEqualTo>
                     <ogc:PropertyName>landuse</ogc:PropertyName>
                     <ogc:Literal>parking</ogc:Literal>
                  </ogc:PropertyIsEqualTo>
               </ogc:Filter>
               <PolygonSymbolizer>
                  <Fill>
                     <CssParameter name="fill">#FF0000</CssParameter>
                     <CssParameter name="fill-opacity">0.5</CssParameter>
                  </Fill>
                  <stroke>
                     <CssParameter name="stroke">#000000</CssParameter>
                     <CssParameter name="stroke-width">1</CssParameter>
                  </stroke>
               </PolygonSymbolizer>
            </Rule>
         </FeatureTypeStyle>
      </UserStyle>
   </NamedLayer>
<StyledLayerDescriptor>

B.2.  Requirements Class “Parameter Values”

Parameter Values are always supported everywhere in SLD/SE and you can assign any type of expression to any symbolizer properties.

Example — SLD Example encoding style using “Parameter Values” requirements class

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<StyledLayerDescriptor version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:se="http://www.opengis.net/se">
  <NamedLayer>
    <Name>Landuse</Name>
    <UserStyle>
      <Name>Styling a land use layer</Name>
      <Title>Styling a land use layer</Title>
      <Abstract>Styling land use data with Style &amp; Symbology Parameter Values</Abstract>
      <FeatureTypeStyle>
        <Rule>
          <Name>parking</Name>
          <Filter>
            <PropertyIsEqualTo>
              <PropertyName>landuse</PropertyName>
              <Literal>parking</Literal>
            </PropertyIsEqualTo>
          </Filter>
          <MaxScaleDenominator>200000</MaxScaleDenominator>
          <PolygonSymbolizer>
            <Fill>
              <CssParameter name="fill">#ff0000</CssParameter>
            </Fill>
            <Stroke>
              <CssParameter name="stroke">#000000</CssParameter>
              <CssParameter name="stroke-width">1</CssParameter>
            </Stroke>
          </PolygonSymbolizer>
        </Rule>
      </FeatureTypeStyle>
    </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

B.3.  Requirements Class “Basic Vector Features Styling”

Table B.10 — Mapping of the “Basic Vector Features Styling” requirements class to SLD/SE constructs

ConstructSE Equivalent
Text (inside Marker)<WellKnownName> pointing to a TrueType Font with a <MarkIndex> identifiying the character inside the font inside a <Mark> inside a <Graphic> in a <PointSymbolizer> (only for single characters text)
Font<Font> with <SvgParameter name="font-family">, <SvgParameter name="font-size">, <SvgParameter name="font-style">, <SvgParameter name="font-weight">
TextAlignment<AnchorPoint> inside <PointSymbolizer>, or <AnchorPoint> inside <PointPlacement> inside <LabelPlacement> inside <TextSymbolizer>
Image<Graphic>
Image hotSpot<AnchorPoint> inside <PointSymbolizer>, or <AnchorPoint> inside <PointPlacement> inside <LabelPlacement> inside <TextSymbolizer>
Dot<WellKnownName> inside a <Mark> inside a <Graphic> inside a <PointSymbolizer>
Marker<PointSymbolizer>
Marker opacity<SvgParameter name="fill-opacity"> for SE 1.1.0, <CssParameter name="fill-opacity"> for SLD 1.0.0 inside a <PointSymbolizer>
Marker position<AnchorPoint> inside <PointSymbolizer>
GraphicalUnituom attribute of symbolizers
Stroke<Stroke>
Stroke opacity<SvgParameter name="stroke-opacity"> for SE 1.1.0, <CssParameter name="stroke-opacity"> for SLD 1.0.0
Stroke color<SvgParameter name="stroke"> for SE 1.1.0, <CssParameter name="stroke"> for SLD 1.0.0
Stroke width<SvgParameter name="stroke-width"> for SE 1.1.0, <CssParameter name="stroke-width"> for SLD 1.0.0
Fill<Fill>
Fill opacity<SvgParameter name="fill-opacity"> for SE 1.1.0, <CssParameter name="fill-opacity"> for SLD 1.0.0
Fill color<SvgParameter name="fill"> for SE 1.1.0, <CssParameter name="fill"> for SLD 1.0.0
Colorfill or stroke with <SvgParameter> (e.g., <SvgParameter name="fill">#000000</SvgParameter>)

Example — SLD Example encoding style using “Basic Vector Features Styling” requirements class

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<StyledLayerDescriptor version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:se="http://www.opengis.net/se">
  <NamedLayer>
    <Name>Landuse</Name>
    <UserStyle>
      <Name>Styling a land use layer</Name>
      <Title>Styling a land use layer</Title>
      <Abstract>Styling land use data with Style &amp; Symbology Parameter Values</Abstract>
      <FeatureTypeStyle>
        <Rule>
          <Name>parking</Name>
          <Filter>
            <PropertyIsEqualTo>
              <PropertyName>landuse</PropertyName>
              <Literal>parking</Literal>
            </PropertyIsEqualTo>
          </Filter>
          <MaxScaleDenominator>200000</MaxScaleDenominator>
          <PointSymbolizer>
            <Graphic>
              <ExternalGraphic>
                <OnlineResource xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/Parking_icon.svg/128px-Parking_icon.svg.png"/>
              </ExternalGraphic>
            </Graphic>
          </PointSymbolizer>
        </Rule>
      </FeatureTypeStyle>
    </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

B.4.  Requirements Class “Basic Coverage Styling”

Table B.11 — Mapping of the “Basic Coverage Styling” requirements class to SLD/SE constructs

ConstructSE Equivalent
ColorChannels<ChannelSelection> with <RedChannel>, <GreenChannel> or <BlueChannel> for RasterSymbolizer
AlphaChannelN/A
SingleChannel<ChannelSelection> with <GrayChannel> for RasterSymbolizer
ColorMap<ColorMap>
OpacityMapN/A
Color<Value> inside <ColorMap>
ValueColor<Value> and <Threshold> inside <Categorize> inside <ColorMap> for SE 1.1.0, <ColorMapEntry> for SLD 1.0.0
ValueOpacity<ColorMapEntry>
Hill Shading
AzimuthElevationN/A
HillShading<ShadedRelief>
HillShading factor<ReliefFactor> in <ShadedRelief>
Contrast Enhancement
contrastEnhancement<ContrastEnhancement>

Example — SLD Example encoding style rendering DEM with a color map using “Basic Coverage Styling” requirements class

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<StyledLayerDescriptor version="1.1.0" xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:se="http://www.opengis.net/se">
   <NamedLayer>
      <Name>Elevation</Name>
      <UserStyle>
         <Name>DEM with color map</Name>
         <Abstract>Applying a color map to a Digital Elevation Model with Style &amp; Symbology Basic Coverage Styling</Abstract>
         <FeatureTypeStyle>
            <Rule>
               <Name>DEM with color map</Name>
               <Title>DEM with color map</Title>
               <MaxScaleDenominator>200000</MaxScaleDenominator>
               <sld:RasterSymbolizer>
                  <sld:Opacity>0.8</sld:Opacity>
                  <sld:ChannelSelection>
                     <sld:GrayChannel>
                        <sld:SourceChannelName>elevation</sld:SourceChannelName>
                     </sld:GrayChannel>
                  </sld:ChannelSelection>
                  <sld:ColorMap>
                     <sld:ColorMapEntry color="#608849" quantity="0" label="0"/>
                     <sld:ColorMapEntry color="#E2DBA7" quantity="900" label="900"/>
                     <sld:ColorMapEntry color="#FCC575" quantity="1300" label="1300"/>
                     <sld:ColorMapEntry color="#FCA886" quantity="1900" label="1900"/>
                     <sld:ColorMapEntry color="#FAFAFA" quantity="2500" label="2500"/>
                  </sld:ColorMap>
               </sld:RasterSymbolizer>
            </Rule>
         </FeatureTypeStyle>
      </UserStyle>
   </NamedLayer>
</StyledLayerDescriptor>

B.5.  Requirements Class “Basic Labeling”

Table B.12 — Mapping of the “Basic Labeling” & “Font Outlines” requirements class to SLD/SE constructs

ConstructSLD Equivalent
Text (inside Label)<Label> inside <TextSymbolizer>
Label<Label> inside <TextSymbolizer> (no support for image or shape labels in SLD 1.0.0)
LabelPlacement<LabelPlacement>
ImageOutlineN/A
Font<Font> with <SvgParameter name="font-family">, <SvgParameter name="font-size">, <SvgParameter name="font-style">, <SvgParameter name="font-weight">
FontOutline<Halo>

Example — SLD Example encoding style using “Basic Labeling” requirements class

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<StyledLayerDescriptor version="1.1.0" xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:se="http://www.opengis.net/se">
   <NamedLayer>
      <Name>Landuse</Name>
      <UserStyle>
         <Name>Styling a land use layer</Name>
         <Abstract>Styling land use data with Style &amp; Symbology Basic Labeling</Abstract>
         <FeatureTypeStyle>
            <Rule>
               <Name>parking</Name>
               <Title>parking</Title>
               <TextSymbolizer>
                <Label>
                  <ogc:PropertyName>name</ogc:PropertyName>
                </Label>
                <Font>
                  <CssParameter name="font-family">Arial</CssParameter>
                  <CssParameter name="font-size">12</CssParameter>
                  <CssParameter name="font-style">normal</CssParameter>
                  <CssParameter name="font-weight">bold</CssParameter>
                </Font>
                <LabelPlacement>
                  <PointPlacement>
                    <AnchorPoint>
                      <AnchorPointX>0.5</AnchorPointX>
                      <AnchorPointY>0.0</AnchorPointY>
                    </AnchorPoint>
                    <Displacement>
                      <DisplacementX>0</DisplacementX>
                      <DisplacementY>25</DisplacementY>
                    </Displacement>
                    <Rotation>-45</Rotation>
                  </PointPlacement>
                </LabelPlacement>
                <Fill>
                  <CssParameter name="fill">#990099</CssParameter>
                </Fill>
               </TextSymbolizer>
            </Rule>
         </FeatureTypeStyle>
      </UserStyle>
   </NamedLayer>
</StyledLayerDescriptor>

B.6.  Requirements Class “Dashes”

Table B.13 — Mapping of the “Dashes” requirements class to SLD/SE constructs

ConstructSE Equivalent
dashPattern`<CssParameter name=”stroke-dasharray”>
dashOffset<CssParameter name="stroke-dashoffset">

Example — SLD Example encoding style using “Dashes” requirements class

 

<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.1.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ogr="http://www.opengis.net/ogr"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd">
   <NamedLayer>
      <Name>Landuse</Name>
      <UserStyle>
         <Name>Styling a land use layer</Name>
         <Abstract>Styling land use data with Style &amp; Symbology Dashes</Abstract>
         <FeatureTypeStyle>
            <Rule>
               <Name>parking</Name>
               <Title>parking</Title>
               <LineSymbolizer>
                  <Stroke>
                     <CssParameter name="stroke">#000000</CssParameter>
                     <CssParameter name="stroke-width">1</CssParameter>
                     <CssParameter name="stroke-dasharray">5 2 1 2</CssParameter>
                     <CssParameter name="stroke-dashoffset">2</CssParameter>
                  </Stroke>
               </LineSymbolizer>
            </Rule>
         </FeatureTypeStyle>
      </UserStyle>
   </NamedLayer>
</StyledLayerDescriptor>

B.7.  Requirements Class “Casing and Centerline”

Table B.14 — Mapping of the “Casing and Centerline” requirements class to SLD/SE constructs

ConstructSE Equivalent
casingmultiple <UserStyle> with different stroke widths
centermultiple <UserStyle> with different stroke widths

Example — SLD Example encoding style using “Casing and Centerline” requirements class

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<StyledLayerDescriptor version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:se="http://www.opengis.net/se">
  <NamedLayer>
    <Name>Casing and Centerline</Name>
    <UserStyle>
      <Name>Casing</Name>
      <Title>Casing</Title>
      <FeatureTypeStyle>
        <Rule>
          <Name>Casing</Name>
          <LineSymbolizer>
            <Stroke>
              <CssParameter name="stroke">#000000</CssParameter>
              <CssParameter name="stroke-width">100</CssParameter>
            </Stroke>
          </LineSymbolizer>
        </Rule>
      </FeatureTypeStyle>
    </UserStyle>
    <UserStyle>
      <Name>Centerline</Name>
      <Title>Centerline</Title>
      <FeatureTypeStyle>
        <Rule>
          <Name>Centerline</Name>
          <LineSymbolizer>
            <Stroke>
              <CssParameter name="stroke">#ffffff</CssParameter>
              <CssParameter name="stroke-width">30</CssParameter>
            </Stroke>
          </LineSymbolizer>
        </Rule>
      </FeatureTypeStyle>
    </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

B.8.  Requirements Class “Hatch fills”

Table B.15 — Mapping of the “Hatch fills” requirements class to SLD/SE constructs

ConstructSE Equivalent
HatchStyleExtended (GeoServer) <WellknownName> prefixed by shape:// (vertline, horline, slash, backslash, plus, times) inside <Mark> inside <Graphic> inside <GraphicFill> and CssParameter such as stroke, stroke-width etc

Example — SLD Example encoding style using “Hatch fills” requirements class

 

?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor
xmlns="http://www.opengis.net/sld"
xmlns:sld="http://www.opengis.net/sld"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:gml="http://www.opengis.net/gml"
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0.0">
  <NamedLayer>
    <UserStyle>
      <Name>tl 2010 08013 arealm</Name>
      <Title/>
      <FeatureTypeStyle>
        <Rule>
          <Name>cemeteries</Name>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>MTFCC</ogc:PropertyName>
              <ogc:Literal>K2582</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <MaxScaleDenominator>500000.0</MaxScaleDenominator>
          <sld:PolygonSymbolizer>
            <Fill>
              <GraphicFill>
                <Graphic>
                  <Mark>
                    <WellKnownName>shape://times</WellKnownName>
                    <Fill/>
                    <Stroke>
                      <CssParameter name="stroke">#ADD8E6</CssParameter>
                      <CssParameter name="stroke-width">1.0</CssParameter>
                    </Stroke>
                  </Mark>
                </Graphic>
              </GraphicFill>
            </Fill>
          </sld:PolygonSymbolizer>
        </Rule>
      </FeatureTypeStyle>
    </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

B.9.  Requirements Class “Stipple fills”

Table B.16 — Mapping of the “Stipple fills” requirements class to SLD/SE constructs

ConstructSE Equivalent
StippleStyleExtended (GeoServer) <WellknownName> shape://dot inside <Mark> inside <Graphic> inside <GraphicFill> and CssParameter such as stroke, stroke-width etc

Example — SLD Example encoding style using “Stipple fills” requirements class

 

?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor
xmlns="http://www.opengis.net/sld"
xmlns:sld="http://www.opengis.net/sld"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:gml="http://www.opengis.net/gml"
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0.0">
  <NamedLayer>
    <UserStyle>
      <Name>tl 2010 08013 arealm</Name>
      <Title/>
      <FeatureTypeStyle>
        <Rule>
          <Name>cemeteries</Name>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>MTFCC</ogc:PropertyName>
              <ogc:Literal>K2582</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <MaxScaleDenominator>500000.0</MaxScaleDenominator>
          <sld:PolygonSymbolizer>
            <Fill>
              <GraphicFill>
                <Graphic>
                  <sld:ExternalGraphic>
                    <sld:OnlineResource
                    xlink:type="simple"
                    xlink:href="./img/landmarks/area/grave_yard.png" />
                    <sld:Format>image/png</sld:Format>
                  </sld:ExternalGraphic>
                </Graphic>
              </GraphicFill>
            </Fill>
          </sld:PolygonSymbolizer>
        </Rule>
      </FeatureTypeStyle>
    </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

B.10.  Requirements Class “Conditional Expressions”

Table B.17 — Mapping of the “Conditional Expressions” requirements class to SLD/SE constructs

ConstructSLD Equivalent
conditional operatorif_then_else <ogc:Function> in GeoServer

Example — SLD Example encoding style using “Conditional Expressions” requirements class

 

<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.1.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ogr="http://www.opengis.net/ogr"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd">
   <NamedLayer>
      <Name>Landuse</Name>
      <UserStyle>
         <Name>Styling a land use layer</Name>
         <Abstract>Styling land use data with Style &amp; Symbology Conditional Expressions</Abstract>
         <FeatureTypeStyle>
            <Rule>
               <Name>parking</Name>
               <Title>parking</Title>
               <PolygonSymbolizer>
                  <Fill>
                     <CssParameter name="fill">
                        <ogc:Function name="if_then_else">
                           <ogc:Function name="PropertyIsEqualTo">
                              <ogc:PropertyName>landuse</ogc:PropertyName>
                              <ogc:Literal>parking</ogc:Literal>
                           </ogc:Function>
                           <ogc:Literal>#FF0000</ogc:Literal>
                           <ogc:Literal>#00FF00</ogc:Literal>
                        </ogc:Function>
                     </CssParameter>
                     <CssParameter name="fill-opacity">0.5</CssParameter>
                  </Fill>
               </PolygonSymbolizer>
            </Rule>
         </FeatureTypeStyle>
      </UserStyle>
   </NamedLayer>
</StyledLayerDescriptor>

B.11.  Requirements Class “Variables”

Table B.18 — Mapping of the “Variables” requirements class to SLD/SE constructs

ConstructSE Equivalent
VariableExpressionN/A

B.12.  Requirements Class “Arithmetic Operators”

Table B.19 — Mapping of the “Arithmetic Operators” requirements class to SLD/SE constructs

ConstructSE Equivalent
ArithmeticOperator
add<ogc:Add>
sub<ogc:Sub>
mul<ogc:Mul>
div<ogc:Div>
intDiv<ogc:Function>
mod<ogc:Function>
pow<ogc:Function>

Example — SLD Example encoding style using “Arithmetic Operators” requirements class

 

<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.1.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ogr="http://www.opengis.net/ogr"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd">
   <NamedLayer>
      <Name>Landuse</Name>
      <UserStyle>
         <Name>Styling a land use layer</Name>
         <Abstract>Styling land use data with Style &amp; Symbology Arithmetic Operators</Abstract>
         <FeatureTypeStyle>
            <Rule>
               <Name>parking</Name>
               <Title>parking</Title>
               <PolygonSymbolizer>
                  <Fill>
                     <CssParameter name="fill">
                        <ogc:Function name="add">
                           <ogc:PropertyName>landuse</ogc:PropertyName>
                           <ogc:Literal>parking</ogc:Literal>
                        </ogc:Function>
                     </CssParameter>
                     <CssParameter name="fill-opacity">0.5</CssParameter>
                  </Fill>
               </PolygonSymbolizer>
            </Rule>
         </FeatureTypeStyle>
      </UserStyle>
   </NamedLayer>
</StyledLayerDescriptor>

B.13.  Requirements Class “Text Relation Operators”

Table B.20 — Mapping of the “Text Relation Operators” requirements class to SLD/SE constructs

ConstructSE Equivalent
TextRelationOperator
like<ogc:Function>
notLike<ogc:Function>
contains<ogc:Function>
startsWith<ogc:Function>
endsWith<ogc:Function>
notContains<ogc:Function>
notStartsWith<ogc:Function>
notEndsWith<ogc:Function>
like<ogc:Function>
notLike<ogc:Function>
contains<ogc:Function>
startsWith<ogc:Function>
endsWith<ogc:Function>
notContains<ogc:Function>
notStartsWith<ogc:Function>
notEndsWith<ogc:Function>

Example — SLD Example encoding style using “Text Relation Operators” requirements class

 

<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.1.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ogr="http://www.opengis.net/ogr"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd">
   <NamedLayer>
      <Name>Landuse</Name>
      <UserStyle>
         <Name>Styling a land use layer</Name>
         <Abstract>Styling land use data with Style &amp; Symbology Text Relation Operators</Abstract>
         <FeatureTypeStyle>
            <Rule>
               <Name>parking</Name>
               <Title>parking</Title>
               <PolygonSymbolizer>
                  <Fill>
                     <CssParameter name="fill">
                        <ogc:Function name="like">
                           <ogc:PropertyName>landuse</ogc:PropertyName>
                           <ogc:Literal>parking</ogc:Literal>
                        </ogc:Function>
                     </CssParameter>
                     <CssParameter name="fill-opacity">0.5</CssParameter>
                  </Fill>
               </PolygonSymbolizer>
            </Rule>
         </FeatureTypeStyle>
      </UserStyle>
   </NamedLayer>
</StyledLayerDescriptor>

B.14.  Requirements Class “Function Expressions”

Table B.21 — Mapping of the “Function Expressions” requirements class to SLD/SE constructs

ConstructSE Equivalent
FunctionCallExpression<ogc:Function>
Function<ogc:Function>
uri<ogc:Function>

Example — SLD Example encoding style using “Function Expressions” requirements class

 

<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.1.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ogr="http://www.opengis.net/ogr"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd">
   <NamedLayer>
      <Name>Landuse</Name>
      <UserStyle>
         <Name>Styling a land use layer</Name>
         <Abstract>Styling land use data with Style &amp; Symbology Function Expressions</Abstract>
         <FeatureTypeStyle>
            <Rule>
               <Name>parking</Name>
               <Title>parking</Title>
               <PolygonSymbolizer>
                  <Fill>
                     <CssParameter name="fill">
                        <ogc:Function name="uri">
                           <ogc:Literal>http://www.opengis.net/ogc</ogc:Literal>
                        </ogc:Function>
                     </CssParameter>
                     <CssParameter name="fill-opacity">0.5</CssParameter>
                  </Fill>
               </PolygonSymbolizer>
            </Rule>
         </FeatureTypeStyle>
      </UserStyle>
   </NamedLayer>
</StyledLayerDescriptor>

B.15.  Requirements Class “Math Functions”

Table B.22 — Mapping of the “Math Functions” requirements class to SLD/SE constructs

ConstructSE Equivalent
MathFunctions<ogc:Function>
absN/A
acosN/A
asinN/A
atanN/A
atan2N/A
ceilN/A
cosN/A
coshN/A
expN/A
floorN/A
logN/A
log10N/A
maxN/A
minN/A
powN/A
randomN/A
rintN/A
roundN/A
sinN/A
sinhN/A
sqrtN/A
tanN/A
tanhN/A

Example — SLD Example encoding style using “Math Functions” requirements class

 

<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.1.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ogr="http://www.opengis.net/ogr"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd">
   <NamedLayer>
      <Name>Landuse</Name>
      <UserStyle>
         <Name>Styling a land use layer</Name>
         <Abstract>Styling land use data with Style &amp; Symbology Math Functions</Abstract>
         <FeatureTypeStyle>
            <Rule>
               <Name>parking</Name>
               <Title>parking</Title>
               <PolygonSymbolizer>
                  <Fill>
                     <CssParameter name="fill">
                        <ogc:Function name="round">
                           <ogc:PropertyName>surface</ogc:PropertyName>
                        </ogc:Function>
                     </CssParameter>
                     <CssParameter name="fill-opacity">0.5</CssParameter>
                  </Fill>
               </PolygonSymbolizer>
            </Rule>
         </FeatureTypeStyle>
      </UserStyle>
   </NamedLayer>
</StyledLayerDescriptor>

B.16.  Requirements Class “Array Relation Functions”

Table B.23 — Mapping of the “Array Relation Functions” requirements class to SLD/SE constructs

ConstructSE Equivalent
ArrayRelationFunctions<ogc:Function>
a_containedBy<ogc:Function>
a_contains<ogc:Function>
a_equals<ogc:Function>
a_overlaps<ogc:Function>

Example — SLD Example encoding style using “Array Relation Functions” requirements class

 

<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.1.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ogr="http://www.opengis.net/ogr"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd">
   <NamedLayer>
      <Name>Landuse</Name>
      <UserStyle>
         <Name>Styling a land use layer</Name>
         <Abstract>Styling land use data with Style &amp; Symbology Array Relation Functions</Abstract>
         <FeatureTypeStyle>
            <Rule>
               <Name>parking</Name>
               <Title>parking</Title>
               <PolygonSymbolizer>
                  <Fill>
                     <CssParameter name="fill">
                        <ogc:Function name="a_containedBy">
                           <ogc:PropertyName>landuse</ogc:PropertyName>
                           <ogc:Literal>parking</ogc:Literal>
                        </ogc:Function>
                     </CssParameter>
                     <CssParameter name="fill-opacity">0.5</CssParameter>
                  </Fill>
               </PolygonSymbolizer>
            </Rule>
         </FeatureTypeStyle>
      </UserStyle>
   </NamedLayer>
</StyledLayerDescriptor>

B.17.  Requirements Class “Text Manipulation Functions”

Table B.24 — Mapping of the “Text Manipulation Functions” requirements class to SLD/SE constructs

ConstructSE Equivalent
TextManipulationFunctions<ogc:Function>
caseInsensitize<ogc:Function>
accentInsensitize<ogc:Function>
lowerCase<ogc:Function>
upperCase<ogc:Function>
concatenate<ogc:Function>
substitute<ogc:Function>
format<ogc:Function>

Example — SLD Example encoding style using “Text Manipulation Functions” requirements class

 

<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.1.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ogr="http://www.opengis.net/ogr"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd">
   <NamedLayer>
      <Name>Landuse</Name>
      <UserStyle>
         <Name>Styling a land use layer</Name>
         <Abstract>Styling land use data with Style &amp; Symbology Text Manipulation Functions</Abstract>
         <FeatureTypeStyle>
            <Rule>
               <Name>parking</Name>
               <Title>parking</Title>
               <TextSymbolizer>
                  <Label>
                     <ogc:Function name="strCapitalize">
                        <ogc:PropertyName>landuse</ogc:PropertyName>
                     </ogc:Function>
                  </Label>
               </TextSymbolizer>
            </Rule>
         </FeatureTypeStyle>
      </UserStyle>
   </NamedLayer>
</StyledLayerDescriptor>

Annex C
(informative)
Portrayal Use Cases Gallery

This annex illustrates the capabilities of the different requirements classes defined in this standard with a map gallery of practical use cases alongside the styles used to generate the maps encoded in the Cascading Styles and Symbology Stylesheets encoding defined in this Standard.

See supplementary materials for same style sheets encoded using the JSON Styles & Symbology encoding.

C.1.  Choropleth (graduated map)

Requirements class used:

Data sources used

  • A rectangular grid of the fraction of high vegetation.

Example — Style encoded using CartoSym-CSS encoding

 

{
  // Note: The following line is optional as 1 pixel black stroke is the default
  stroke: { black; width: 1px }
  [highVegetationFract between 0   and 0.2] { fill: { yellow }; };
  [highVegetationFract between 0.2 and 0.5] { fill: { orange }; };
  [highVegetationFract > 0.5]               { fill: { red } };
}

 

Figure C.1 — Example rendering of the Choropleth map

C.2.  Overriding rules

Requirements class used:

Data sources used

  • Circumpolar distribution and carbon storage of thermokarst landscapes

Citation: Olefeldt, D., Goswami, S., Grosse, G., Hayes, D., Hugelius, G., Kuhry, P., McGuire, A.D, Romanovsky, V.E, Sannel, A.B.K., Schuur, E.A.G., Turetsky, M.R: Circumpolar distribution and carbon storage of thermokarst landscapes. Nature Communications, 7, 13043. Available at: https://www.nature.com/articles/ncomms13043#f3 (2016)

Example — Style encoded using CartoSym-CSS encoding

 

#Thermokarst
{
   stroke: { width: 0 };
   [TKWP = 'Low'                                    ]{ fill: { #a1ff74 }; }
   [TKThLP = 'Low'                                  ]{ fill: { #74b2ff }; }
   [TKHP = 'Low'                                    ]{ fill: { #fd846d }; }
   [TKWP = 'Low' AND TKHP = 'Low'                   ]{ fill: { #f7ff7c }; }
   [TKWP = 'Low' AND TKThLP = 'Low'                 ]{ fill: { #beffe9 }; }
   [TKWP = 'Low' AND TKThLP = 'Low' AND TKHP = 'Low']{ fill: { #9d9d9d }; }
   [TKWP = 'Moderate'                               ]{ fill: { #4de600 }; }
   [TKThLP = 'Moderate'                             ]{ fill: { #0070ff }; }
   [TKHP = 'Moderate'                               ]{ fill: { #fe0001 }; }
   [TKWP = 'Moderate' AND TKHP = 'Moderate'         ]{ fill: { #eae600 }; }
   [TKThLP = 'Moderate' AND TKHP = 'Moderate'       ]{ fill: { #ff00c4 }; }
   [TKWP = 'Moderate' AND TKThLP = 'Moderate'       ]{ fill: { #00e7a9 }; }
   [TKWP = 'High'                                   ]{ fill: { #39a60d }; }
   [TKThLP = 'High'                                 ]{ fill: { #014da9 }; }
   [TKHP = 'High'                                   ]{ fill: { #9a0602 }; }
   [TKWP = 'High' AND TKThLP = 'High'               ]{ fill: { #00a882 }; }
   [TKWP = 'Very High'                              ]{ fill: { #334d27 }; }
   [TKThLP = 'Very High'                            ]{ fill: { #002674 }; }
   [TKWP = 'Very High' AND TKThLP = 'Very High'     ]{ fill: { #007f7e }; }
}

 

Figure C.2 — Example rendering of the thermokarst landscapes

C.3.  Visualization passes

 

Figure C.3 — Example rendering of complex visual ordering (placeholder from GeoServer documentation)

Example — CartoSym-CSS Example showcasing use of viz.pass for both casing and ordering based on z_order attribute

 

{
   [viz.pass = 4 * z_order + 0]
   {
      [class = 'railways'][bridge = 1] { stroke: { color: #333333; width: 8; }; }
      [class = 'minorroads']           { stroke: { color: #a69269; width: 3; }; }
      [class = 'mainroads']            { stroke: { color: #ff0000; width: 5; }; }
      [class = 'motorways']            { stroke: { color: #990000; width: 8; }; }
   }

   [viz.pass = 4 * z_order + 1]
   {
      [class = 'railways'][bridge = 1] { stroke: { color: #ffffff; width: 6; }; }
   }

   [viz.pass = 4 * z_order + 2]
   {
      [class = 'railways'] { stroke: { color: #333333; width: 3; }; }
   }

   [viz.pass = 4 * z_order + 3]
   {
      [class = 'railways]    { stroke: { color: #ffffff; width: 1.5; dashPattern: 5, 5; }; }
      [class = 'motorways']  { stroke: { color: #ff6666; width: 6;   cap: round; }; }
      [class = 'minorroads'] { stroke: { color: #ffffff; width: 2.5; cap: round; }; }
      [class = 'mainroads']  { stroke: { color: #ff9999; width: 4;   cap: round; }; }
   }
}

C.4.  Z-ordering and feature rendering passes

Example — CartoSym-CSS Example using built-in casing

 

{
   zOrder: z_order;
   [feature.pass = -1][class = 'railways'][bridge = 1]
   {
      stroke: { color: #ffffff; width: 6; casing: { color: #333333; width: 1; }; };
   }
   [class = 'minorroads']  { stroke: { color: #ffffff; width: 2.5; cap: round;        casing: { color: #a69269; width: 0.25; }; }; }
   [class = 'mainroads']   { stroke: { color: #ff9999; width: 4;   cap: round;        casing: { color: #ff0000; width: 0.5;  }; }; }
   [class = 'motorways']   { stroke: { color: #ff6666; width: 6;   cap: round;        casing: { color: #990000; width: 1;    }; }; }
   [class = 'railways']    { stroke: { color: #ffffff; width: 1.5; dashPattern: 5, 5; casing: { color: #333333; width: 0.75; }; }; }
}

C.5.  Natural Earth (economies)

 

Figure C.4 — Example rendering of the Natural Earth map, colored by economies

Example — CartoSym-CSS used to produce above Natural Earth map colored by economies

 

.title 'Economy status by country'
.abstract 'This style is used to draw the economic status of the natural earth countries.\n'
          'This style uses the natural earth shapefile available at https://www.naturalearthdata.com/downloads/10m-cultural-vectors/10m-admin-0-countries/'

.keywords 'Econonomy, Country, World'

ne_10m_admin_0_countries[dataLayer.type = vector]
{
    visibility: true;
    zOrder: 1;
    stroke: {color: gray; width: 2.0 px; opacity: 1.0};
    label : { elements: [
            Text {
             text : NAME,
             font:{
             face:'Arial',
             size:8,
             color:black
             }
                }]
            };

   [ECONOMY = '1. Developed region: G7']
   {
    fill.color : #707e70;
   }
   [ECONOMY = '2. Developed region: nonG7']
   {
    fill.color : #97aa97;
   }
   [ECONOMY = '3. Emerging region: BRIC']
   {
    fill.color : #adaa07;
   }
   [ECONOMY = '4. Emerging region: MIKT']
   {
    fill.color : #d0cd08;
   }
   [ECONOMY = '5. Emerging region: G20']
   {
    fill.color : #e9e509;
   }
   [ECONOMY = '6. Developing region']
   {
    fill.color : #e67d3c;
   }
   [ECONOMY = '7. Least developed region']
   {
    fill.color : #834722;
   }
}

C.6.  Natural Earth (continents)

 

Figure C.5 — Example rendering of the Natural Earth map, colored by continent

Example — CartoSym-CSS used to produce above Natural Earth map colored by continents

 

{ visibility: false; }

ne_10m_admin_0_countries
{
   visibility: true;
   zOrder: 1;
   opacity: 0.3686275;

   label: { elements: [ Text { text: name,
                               font: { face: 'Tahoma',
                                       size: 14,
                                       outline: { size: 3,
                                                  opacity: 0.75,
                                                  color: white }
                                      }
                               } ] };

   [CONTINENT = 'Africa']
   {
      fill.color: #e29176;
   }

   [CONTINENT = 'Antartica']
   {
      fill.color: #3a0fc8;
   }

   [CONTINENT = 'Asia']
   {
      fill.color: #3a0fc8;
   }

   [CONTINENT = 'Europe']
   {
      fill.color: #d2c85c;
   }

   [CONTINENT = 'North America']
   {
      fill.color: #15ed4b;
   }

   [CONTINENT = 'Oceania']
   {
      fill.color: #3ad3c6;
   }

   [CONTINENT = 'South America']
   {
      fill.color: #ef4b8f;
   }
}

ne_10m_urban_areas
{
   visibility: true;
   fill: { opacity: 0.8, color: #ffe469 };
   stroke: { color: yellow, width: 0 };
   zOrder: 31;
}

ne_10m_graticules_10
{
   visibility: true;
   stroke: { color: gainsboro, width: 0.1 };
   zOrder: 3;
}

ne_10m_graticules_30
{
   visibility: true;
   stroke: { color: gray, width: 0.1 };
   zOrder: 4;
}

ne_10m_populated_places
{
   visibility: true;
   zOrder: 24;

   [SCALERANK = 0]
   {
      label: { elements: [
         Dot { color: white, size: 10 },
         Dot { color: darkOrange, size: 6 },
         Text { text: NAME,
                position2D : { 10, -4 },
                font: { face: 'Tahoma',
                        size: 12,
                        outline: { color: white,
                                   size: 3.5,
                                   opacity: 0.75 }
                       },
                alignment: { left, middle } }
      ] };
   }
}

ne_10m_geography_regions_polys
{
   visibility: true;
   fill: { opacity: 0 };
   stroke: { width: 0 };
   label: { elements: [ Text {
                  text: name,
                  font: { face: 'Times New Roman',
                  size: 12,
                  italic: true,
                  color: papayaWhip,
                  outline: { size: 3,
                             color: black,
                             opacity: 0.35 }
                         },
                  alignment: { center, middle }
                               }
                      ] };
   zOrder: 64;
}

ne_10m_bathymetry_I_2000
{
   visibility: true;
   fill: { color: #95bce6 };
   stroke: { width: 0, opacity: 0 };
   zOrder: 3;
}

ne_10m_bathymetry_L_0
{
   visibility: true;
   fill: { color: #d1e9ff };
   stroke: { width: 0, opacity: 0 };
   zOrder: 0;
}

ne_10m_bathymetry_K_200
{
   visibility: true;
   fill: { color: #bfe0ff };
   stroke: { width: 0, opacity: 0 };
   zOrder: 1;
}

ne_10m_bathymetry_J_1000
{
   visibility: true;
   fill: { color: #aacff2 };
   stroke: { width: 0, opacity: 0 };
   zOrder: 2;
}

ne_10m_bathymetry_H_3000
{
   visibility: true;
   fill: { color: #86b3eb };
   stroke: { width: 0, opacity: 0 };
   zOrder: 4;
}

ne_10m_bathymetry_G_4000
{
   visibility: true;
   fill: { color: #629fd9 };
   stroke: { width: 0, opacity: 0 };
   zOrder: 5;
}

ne_10m_bathymetry_F_5000
{
   visibility: true;
   fill: { color: #528fcc };
   stroke: { width: 0, opacity: 0 };
   zOrder: 6;
}

ne_10m_bathymetry_E_6000
{
   visibility: true;
   fill: { color: #427cb3 };
   stroke: { width: 0, opacity: 0 };
   zOrder: 7;
}

ne_10m_bathymetry_D_7000
{
   visibility: true;
   fill: { color: #2b66a6 };
   stroke: { width: 0, opacity: 0 };
   zOrder: 8;
}

ne_10m_bathymetry_C_8000
{
   visibility: true;
   fill: { color: #385b8c };
   stroke: { width: 0, opacity: 0 };
   zOrder: 9;
}

ne_10m_bathymetry_B_9000
{
   visibility: true;
   fill: { color: #2a3268 };
   stroke: { width: 0, opacity: 0 };
   zOrder: 10;
}

ne_10m_bathymetry_A_10000
{
   visibility: true;
   fill: { color: #1e1c47 };
   stroke: { width: 0, opacity: 0 };
   zOrder: 11;
}

ne_10m_playas
{
   visibility: true;
   opacity: 0.4235294;
   fill: { color: burlyWood };
   stroke: { width: 0 };
   zOrder: 75;
}

ne_10m_ocean
{
   visibility: true;
   fill: { color: #e4f4f7 };
   stroke: { width: 0 };
   zOrder: 4;
}

ne_10m_admin_1_states_provinces
{
   visibility: true;
   fill: { opacity: 0 };
   stroke: { color: silver, width: 0.5 };
   zOrder: 3;
}

ne_10m_rivers_lake_centerlines
{
   visibility: true;
   stroke: { color: dodgerBlue, width: 0.5 };
   zOrder: 36;
}

ne_10m_rivers_europe
{
   visibility: true;
   stroke: { color: dodgerBlue, width: 0.5 };
   zOrder: 25;
}

ne_10m_reefs
{
   visibility: true;
   stroke: { color: #00af7a };
   zOrder: 35;
}

ne_10m_lakes_pluvial
{
   visibility: true;
   fill: { color: dodgerBlue };
   stroke: { width: 0 };
   zOrder: 22;
}

ne_10m_lakes_north_america
{
   visibility: true;
   fill: { color: dodgerBlue };
   stroke: { width: 0 };
   zOrder: 70;
}

ne_10m_lakes_europe
{
   visibility: true;
   fill: { color: dodgerBlue };
   stroke: { width: 0 };
   zOrder: 68;
}

ne_10m_lakes
{
   visibility: true;
   fill: { color: dodgerBlue };
   stroke: { width: 0 };
   zOrder: 67;
}

ne_10m_glaciated_areas
{
   visibility: true;
   fill: { opacity: 0.16, color: aqua };
   stroke: { width: 0 };
   zOrder: 65;
}

ne_10m_geography_marine_polys
{
   visibility: true;
   fill: { opacity: 0 };
   stroke: { width: 0 };
   zOrder: 87;
   [SCALERANK = 0]
   {
      label: { elements: [ Text { text: name,
                                  font: { face: 'Tahoma',
                                          size: 12,
                                          color: dodgerBlue,
                                          italic: true,
                                          outline: { size: 3,
                                                     opacity: 0.75,
                                                     color: #10508b
                                                    }
                                         } } ] };
   }
}

ne_10m_roads
{
   visibility: true;
   zOrder: 86;
   [SCALERANK <= 3]{
   stroke: { width: 0.66, color : #c42e31 };
   }
}

Annex D
(informative)
Revision history

Table D.1 — Revision history

DateReleaseAuthorParagraph modifiedDescription
2020-08-27E. Bocher (CNRS) O. Ertz (HEIG-VD)Edits considering received and answered comments from TC vote
2019-09-18E. Bocher (CNRS) O. Ertz (HEIG-VD)Edits considering received and answered comments (18-067r2)
2019-08-21E. Bocher (CNRS) O. Ertz (HEIG-VD)Update abstract to be more comprehensive
2019-03-29E. Bocher (CNRS) O. Ertz (HEIG-VD)Edits considering received and answered comments
2018-09-07E. Bocher (CNRS) O. Ertz (HEIG-VD)Release for early public comment (18-067)
2018-06-05E. Bocher (CNRS) O. Ertz (HEIG-VD)Initial document
2022-12-01E. Bocher (CNRS) O. Ertz & M. Collombin (HEIG-VD), J. St-Louis (Ecere)Initial work towards version 2.0
2023-02-23E. Bocher (CNRS) O. Ertz & M. Collombin (HEIG-VD), J. St-Louis (Ecere)Progress towards 2.0 in preparation for 125th MM in Frascati

Bibliography

This Standard is deeply inspired by the work from the following documents that preceded it:

[1]  Stephane Fellah: OGC 16-059, Testbed-12 Semantic Portrayal, Registry and Mediation Engineering Report. Open Geospatial Consortium (2017). http://www.opengis.net/doc/PER/t12-A066.

[2]  Jeff Yutzler, Rob Cass: OGC 17-094r1, OGC Portrayal Concept Development Study. Open Geospatial Consortium (2018). http://www.opengis.net/doc/PER/portrayalCDS.

[3]  Stephane Fellah: OGC 17-045, OGC Testbed-13: Portrayal Engineering Report. Open Geospatial Consortium (2018). http://www.opengis.net/doc/PER/t13-NG008.

[4]  Jérôme Jacovella-St-Louis: OGC 18-025, OGC Testbed-14: CityGML and AR Engineering Report. Open Geospatial Consortium (2019). http://www.opengis.net/doc/PER/t14-D028.

[5]  Sara Saeedi: OGC 18-029, OGC Testbed-14: Symbology Engineering Report. Open Geospatial Consortium (2019). http://www.opengis.net/doc/PER/t14-D029.

[6]  Martin Klopfer: OGC 19-018, OGC Testbed-15: Open Portrayal Framework Engineering Report. Open Geospatial Consortium (2020). http://www.opengis.net/doc/PER/t15-D015.

[7]  Martin Klopfer: OGC 19-019, OGC Testbed-15: Portrayal Summary ER. Open Geospatial Consortium (2020). http://www.opengis.net/doc/PER/t15-D017.

[8]  Bocher E, Ertz O. 2018. A redesign of OGC Symbology Encoding standard for sharing cartography. PeerJ Computer Science 4:e143, https://doi.org/10.7717/peerj-cs.143